diff --git a/.depend b/.depend index 45fc6b9..134a986 100644 --- a/.depend +++ b/.depend @@ -2,184 +2,176 @@ # Run "make depend" to rebuild. # DO NOT DELETE -addr.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h addr.h -addrmatch.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h addr.h match.h log.h ssherr.h -atomicio.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h atomicio.h -audit-bsm.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -audit-linux.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -audit.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -auth-bsdauth.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -auth-krb5.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h packet.h openbsd-compat/sys-queue.h dispatch.h log.h ssherr.h sshbuf.h sshkey.h misc.h servconf.h uidswap.h hostfile.h auth.h auth-pam.h audit.h loginrec.h -auth-options.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssherr.h log.h sshbuf.h misc.h sshkey.h match.h ssh2.h auth-options.h -auth-pam.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -auth-passwd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h packet.h openbsd-compat/sys-queue.h dispatch.h sshbuf.h ssherr.h log.h misc.h servconf.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h auth-options.h -auth-rhosts.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h packet.h openbsd-compat/sys-queue.h dispatch.h uidswap.h pathnames.h log.h ssherr.h misc.h xmalloc.h sshbuf.h sshkey.h servconf.h canohost.h hostfile.h auth.h auth-pam.h audit.h loginrec.h -auth-shadow.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -auth-sia.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -auth.o: authfile.h monitor_wrap.h channels.h -auth.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h match.h groupaccess.h log.h ssherr.h sshbuf.h misc.h servconf.h openbsd-compat/sys-queue.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h auth-options.h canohost.h uidswap.h packet.h dispatch.h -auth2-chall.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh2.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h sshbuf.h packet.h openbsd-compat/sys-queue.h dispatch.h ssherr.h log.h misc.h servconf.h -auth2-gss.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -auth2-hostbased.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh2.h packet.h openbsd-compat/sys-queue.h dispatch.h kex.h mac.h crypto_api.h sshbuf.h log.h ssherr.h misc.h servconf.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h canohost.h -auth2-hostbased.o: monitor_wrap.h pathnames.h match.h -auth2-kbdint.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h packet.h openbsd-compat/sys-queue.h dispatch.h hostfile.h auth.h auth-pam.h audit.h loginrec.h log.h ssherr.h misc.h servconf.h -auth2-methods.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h misc.h servconf.h openbsd-compat/sys-queue.h xmalloc.h hostfile.h auth.h auth-pam.h audit.h loginrec.h -auth2-none.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h atomicio.h xmalloc.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h packet.h openbsd-compat/sys-queue.h dispatch.h log.h ssherr.h misc.h servconf.h ssh2.h monitor_wrap.h -auth2-passwd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h packet.h openbsd-compat/sys-queue.h dispatch.h ssherr.h log.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h monitor_wrap.h misc.h servconf.h -auth2-pubkey.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h ssh2.h packet.h openbsd-compat/sys-queue.h dispatch.h kex.h mac.h crypto_api.h sshbuf.h log.h ssherr.h misc.h servconf.h compat.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h -auth2-pubkey.o: pathnames.h uidswap.h auth-options.h canohost.h monitor_wrap.h authfile.h match.h channels.h session.h sk-api.h -auth2-pubkeyfile.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssh.h log.h ssherr.h misc.h sshkey.h digest.h hostfile.h auth.h auth-pam.h audit.h loginrec.h auth-options.h authfile.h match.h -auth2.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h atomicio.h xmalloc.h ssh2.h packet.h openbsd-compat/sys-queue.h dispatch.h log.h ssherr.h sshbuf.h misc.h servconf.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h pathnames.h monitor_wrap.h digest.h kex.h -auth2.o: mac.h crypto_api.h -authfd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h sshbuf.h sshkey.h authfd.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h log.h ssherr.h atomicio.h misc.h -authfile.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h ssh.h log.h ssherr.h authfile.h misc.h atomicio.h sshkey.h sshbuf.h krl.h -bitmap.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h bitmap.h -canohost.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h packet.h openbsd-compat/sys-queue.h dispatch.h log.h ssherr.h canohost.h misc.h -chacha.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h chacha.h -channels.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h ssherr.h sshbuf.h packet.h dispatch.h log.h misc.h channels.h compat.h canohost.h sshkey.h authfd.h pathnames.h match.h -cipher-aes.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/openssl-compat.h -cipher-aesctr.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h cipher-aesctr.h rijndael.h -cipher-chachapoly-libcrypto.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -cipher-chachapoly.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h sshbuf.h cipher-chachapoly.h chacha.h poly1305.h -cipher.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h misc.h sshbuf.h ssherr.h digest.h openbsd-compat/openssl-compat.h -cleanup.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h -clientloop.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h packet.h dispatch.h sshbuf.h compat.h channels.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h crypto_api.h -clientloop.o: myproposal.h log.h ssherr.h misc.h readconf.h clientloop.h sshconnect.h authfd.h atomicio.h sshpty.h match.h msg.h hostfile.h -compat.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h packet.h openbsd-compat/sys-queue.h dispatch.h compat.h log.h ssherr.h match.h -dh.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -digest-libc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h digest.h -digest-openssl.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -dispatch.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssh2.h log.h ssherr.h dispatch.h packet.h openbsd-compat/sys-queue.h -dns.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h sshkey.h ssherr.h dns.h log.h digest.h -ed25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h crypto_api.h -entropy.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -fatal.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h -groupaccess.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h groupaccess.h match.h log.h ssherr.h -gss-genr.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -gss-serv-krb5.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -gss-serv.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -hash.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h crypto_api.h -hmac.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshbuf.h digest.h hmac.h -hostfile.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h match.h sshkey.h hostfile.h log.h ssherr.h misc.h pathnames.h digest.h hmac.h sshbuf.h -kex-names.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h kex.h mac.h crypto_api.h log.h ssherr.h match.h digest.h misc.h xmalloc.h -kex.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssh.h ssh2.h atomicio.h version.h packet.h openbsd-compat/sys-queue.h dispatch.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h crypto_api.h log.h ssherr.h -kex.o: match.h misc.h monitor.h myproposal.h sshbuf.h digest.h xmalloc.h -kexc25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshkey.h kex.h mac.h crypto_api.h sshbuf.h digest.h ssherr.h ssh2.h -kexdh.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -kexecdh.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h -kexgen.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshkey.h kex.h mac.h crypto_api.h log.h ssherr.h packet.h openbsd-compat/sys-queue.h dispatch.h ssh2.h sshbuf.h digest.h -kexgex.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -kexgexc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -kexgexs.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -kexmlkem768x25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshkey.h kex.h mac.h crypto_api.h sshbuf.h digest.h ssherr.h log.h -kexsntrup761x25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h -krl.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ./openbsd-compat/sys-tree.h openbsd-compat/sys-queue.h sshbuf.h ssherr.h sshkey.h authfile.h misc.h log.h digest.h bitmap.h utf8.h krl.h -log.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h match.h -loginrec.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h sshkey.h hostfile.h ssh.h loginrec.h log.h ssherr.h atomicio.h packet.h openbsd-compat/sys-queue.h dispatch.h canohost.h auth.h auth-pam.h audit.h sshbuf.h misc.h -logintest.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h loginrec.h -mac.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h digest.h hmac.h umac.h mac.h misc.h ssherr.h sshbuf.h openbsd-compat/openssl-compat.h -match.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h match.h misc.h -misc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h misc.h log.h ssherr.h ssh.h sshbuf.h -moduli.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -monitor.o: chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h crypto_api.h dh.h packet.h dispatch.h auth-options.h sshpty.h channels.h session.h sshlogin.h canohost.h log.h ssherr.h misc.h servconf.h monitor.h monitor_wrap.h monitor_fdpass.h compat.h ssh2.h authfd.h match.h sk-api.h srclimit.h -monitor.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ./openbsd-compat/sys-tree.h openbsd-compat/sys-queue.h openbsd-compat/openssl-compat.h atomicio.h xmalloc.h ssh.h sshkey.h sshbuf.h hostfile.h auth.h auth-pam.h audit.h loginrec.h cipher.h cipher-chachapoly.h -monitor_fdpass.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h monitor_fdpass.h -monitor_wrap.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h sshbuf.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h crypto_api.h hostfile.h auth.h auth-pam.h audit.h -monitor_wrap.o: loginrec.h auth-options.h packet.h dispatch.h log.h ssherr.h monitor.h atomicio.h monitor_fdpass.h misc.h channels.h session.h servconf.h monitor_wrap.h srclimit.h -msg.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshbuf.h ssherr.h log.h atomicio.h msg.h misc.h -mux.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h log.h ssherr.h ssh.h ssh2.h pathnames.h misc.h match.h sshbuf.h channels.h msg.h packet.h dispatch.h monitor_fdpass.h sshpty.h sshkey.h readconf.h clientloop.h -nchan.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h ssh2.h sshbuf.h ssherr.h packet.h dispatch.h channels.h compat.h log.h -packet.o: channels.h ssh.h packet.h dispatch.h sshbuf.h -packet.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h compat.h ssh2.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h crypto_api.h digest.h log.h ssherr.h canohost.h misc.h -platform-listen.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h misc.h -platform-misc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -platform-pledge.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -platform-tracing.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h -platform.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h misc.h servconf.h openbsd-compat/sys-queue.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h -poly1305.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h poly1305.h -progressmeter.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h progressmeter.h atomicio.h misc.h utf8.h -readconf.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/glob.h xmalloc.h ssh.h ssherr.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h pathnames.h log.h sshkey.h misc.h readconf.h match.h kex.h mac.h crypto_api.h uidswap.h -readconf.o: myproposal.h digest.h -readpass.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h misc.h pathnames.h log.h ssherr.h ssh.h uidswap.h -rijndael.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h rijndael.h -sandbox-capsicum.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -sandbox-darwin.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -sandbox-null.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -sandbox-pledge.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -sandbox-rlimit.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -sandbox-seccomp-filter.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -sandbox-solaris.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -sandbox-systrace.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -scp.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/glob.h xmalloc.h ssh.h atomicio.h pathnames.h log.h ssherr.h misc.h progressmeter.h utf8.h sftp.h sftp-common.h sftp-client.h -servconf.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/glob.h openbsd-compat/sys-queue.h xmalloc.h ssh.h log.h ssherr.h sshbuf.h misc.h servconf.h pathnames.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h -servconf.o: mac.h crypto_api.h match.h channels.h groupaccess.h canohost.h packet.h dispatch.h hostfile.h auth.h auth-pam.h audit.h loginrec.h myproposal.h digest.h -serverloop.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h packet.h dispatch.h sshbuf.h log.h ssherr.h misc.h servconf.h canohost.h sshpty.h channels.h ssh2.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h -serverloop.o: rijndael.h kex.h mac.h crypto_api.h hostfile.h auth.h auth-pam.h audit.h loginrec.h session.h auth-options.h serverloop.h -session.o: hostfile.h auth.h auth-pam.h audit.h loginrec.h auth-options.h authfd.h pathnames.h log.h misc.h servconf.h sshlogin.h serverloop.h canohost.h session.h kex.h mac.h crypto_api.h monitor_wrap.h sftp.h atomicio.h -session.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h sshpty.h packet.h dispatch.h sshbuf.h ssherr.h match.h uidswap.h channels.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h -sftp-client.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssherr.h sshbuf.h log.h atomicio.h progressmeter.h misc.h utf8.h sftp.h sftp-common.h sftp-client.h openbsd-compat/glob.h -sftp-common.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssherr.h sshbuf.h log.h misc.h sftp.h sftp-common.h -sftp-glob.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h sftp.h sftp-common.h sftp-client.h openbsd-compat/glob.h -sftp-realpath.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -sftp-server-main.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h sftp.h misc.h xmalloc.h -sftp-server.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h atomicio.h xmalloc.h sshbuf.h ssherr.h log.h misc.h match.h uidswap.h sftp.h sftp-common.h -sftp-usergroup.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ./openbsd-compat/sys-tree.h log.h ssherr.h xmalloc.h sftp-common.h sftp-client.h openbsd-compat/glob.h sftp-usergroup.h -sftp.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h log.h ssherr.h pathnames.h misc.h utf8.h sftp.h sshbuf.h sftp-common.h sftp-client.h openbsd-compat/glob.h sftp-usergroup.h -sk-usbhid.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -sntrup761.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -srclimit.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ./openbsd-compat/sys-tree.h addr.h canohost.h log.h ssherr.h misc.h srclimit.h xmalloc.h servconf.h openbsd-compat/sys-queue.h match.h -ssh-add.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h log.h ssherr.h sshkey.h sshbuf.h authfd.h authfile.h pathnames.h misc.h digest.h ssh-sk.h sk-api.h hostfile.h -ssh-agent.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h sshbuf.h sshkey.h authfd.h log.h ssherr.h misc.h digest.h match.h msg.h pathnames.h ssh-pkcs11.h sk-api.h myproposal.h -ssh-dss.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -ssh-ecdsa-sk.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/openssl-compat.h sshbuf.h ssherr.h digest.h sshkey.h -ssh-ecdsa.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -ssh-ed25519-sk.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h crypto_api.h log.h ssherr.h sshbuf.h sshkey.h ssh.h digest.h -ssh-ed25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h crypto_api.h log.h ssherr.h sshbuf.h sshkey.h ssh.h +addr.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h addr.h +addrmatch.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h addr.h match.h log.h ssherr.h +atomicio.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h atomicio.h +audit-bsm.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +audit-linux.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +audit.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +auth-bsdauth.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +auth-krb5.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h packet.h dispatch.h log.h ssherr.h sshbuf.h sshkey.h misc.h servconf.h uidswap.h hostfile.h auth.h auth-pam.h audit.h loginrec.h +auth-options.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssherr.h log.h sshbuf.h misc.h sshkey.h match.h ssh2.h auth-options.h +auth-pam.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +auth-passwd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h packet.h dispatch.h sshbuf.h ssherr.h log.h misc.h servconf.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h auth-options.h +auth-rhosts.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h packet.h dispatch.h uidswap.h pathnames.h log.h ssherr.h misc.h xmalloc.h sshbuf.h sshkey.h servconf.h canohost.h hostfile.h auth.h auth-pam.h audit.h loginrec.h +auth-shadow.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +auth-sia.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +auth.o: channels.h +auth.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h match.h groupaccess.h log.h ssherr.h sshbuf.h misc.h servconf.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h auth-options.h canohost.h uidswap.h packet.h dispatch.h authfile.h monitor_wrap.h +auth2-chall.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh2.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h sshbuf.h packet.h dispatch.h ssherr.h log.h misc.h servconf.h +auth2-gss.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +auth2-hostbased.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh2.h packet.h dispatch.h kex.h mac.h crypto_api.h sshbuf.h log.h ssherr.h misc.h servconf.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h canohost.h monitor_wrap.h pathnames.h +auth2-hostbased.o: match.h +auth2-kbdint.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h packet.h dispatch.h hostfile.h auth.h auth-pam.h audit.h loginrec.h log.h ssherr.h misc.h servconf.h +auth2-methods.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h misc.h servconf.h xmalloc.h hostfile.h auth.h auth-pam.h audit.h loginrec.h +auth2-none.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h packet.h dispatch.h log.h ssherr.h misc.h servconf.h ssh2.h monitor_wrap.h +auth2-passwd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h packet.h dispatch.h ssherr.h log.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h monitor_wrap.h misc.h servconf.h +auth2-pubkey.o: auth-options.h canohost.h monitor_wrap.h authfile.h match.h channels.h session.h sk-api.h +auth2-pubkey.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h ssh2.h packet.h dispatch.h kex.h mac.h crypto_api.h sshbuf.h log.h ssherr.h misc.h servconf.h compat.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h pathnames.h uidswap.h +auth2-pubkeyfile.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssh.h log.h ssherr.h misc.h sshkey.h digest.h hostfile.h auth.h auth-pam.h audit.h loginrec.h auth-options.h authfile.h match.h xmalloc.h +auth2.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h atomicio.h xmalloc.h ssh2.h packet.h dispatch.h log.h ssherr.h sshbuf.h misc.h servconf.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h pathnames.h monitor_wrap.h digest.h kex.h mac.h crypto_api.h +authfd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssh.h sshbuf.h sshkey.h authfd.h log.h ssherr.h misc.h atomicio.h xmalloc.h +authfile.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h authfile.h sshkey.h sshbuf.h krl.h +bitmap.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h bitmap.h +canohost.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h log.h ssherr.h canohost.h misc.h +chacha.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h chacha.h +channels.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h ssh2.h ssherr.h sshbuf.h packet.h dispatch.h log.h misc.h channels.h compat.h canohost.h pathnames.h match.h +cipher-aes.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/openssl-compat.h +cipher-aesctr.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h cipher-aesctr.h rijndael.h +cipher-chachapoly-libcrypto.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +cipher-chachapoly.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h sshbuf.h cipher-chachapoly.h chacha.h poly1305.h +cipher.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h misc.h sshbuf.h ssherr.h openbsd-compat/openssl-compat.h +cleanup.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h +clientloop.o: hostfile.h +clientloop.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h ssh2.h packet.h dispatch.h sshbuf.h compat.h channels.h sshkey.h kex.h mac.h crypto_api.h log.h ssherr.h misc.h readconf.h clientloop.h sshconnect.h authfd.h atomicio.h sshpty.h match.h +compat.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h packet.h dispatch.h compat.h log.h ssherr.h match.h +dh.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +digest-libc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h digest.h +digest-openssl.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +dispatch.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssh2.h log.h ssherr.h dispatch.h packet.h +dns.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h sshkey.h dns.h log.h ssherr.h digest.h +ed25519-openssl.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +ed25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h crypto_api.h +entropy.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +fatal.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h +groupaccess.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h groupaccess.h match.h log.h ssherr.h +gss-genr.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +gss-serv-krb5.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +gss-serv.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +hmac.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h digest.h hmac.h +hostfile.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h match.h sshkey.h hostfile.h log.h ssherr.h misc.h pathnames.h digest.h hmac.h sshbuf.h +kex-names.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h kex.h mac.h crypto_api.h log.h ssherr.h match.h digest.h misc.h +kex.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssh.h ssh2.h atomicio.h version.h packet.h dispatch.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h crypto_api.h log.h ssherr.h match.h misc.h +kex.o: myproposal.h sshbuf.h digest.h xmalloc.h +kexc25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshkey.h kex.h mac.h crypto_api.h sshbuf.h digest.h ssherr.h ssh2.h +kexdh.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +kexecdh.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h +kexgen.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshkey.h kex.h mac.h crypto_api.h log.h ssherr.h packet.h dispatch.h ssh2.h sshbuf.h digest.h +kexgex.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +kexgexc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +kexgexs.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +kexmlkem768x25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshkey.h kex.h mac.h crypto_api.h sshbuf.h digest.h ssherr.h log.h +kexsntrup761x25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h +krl.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshbuf.h ssherr.h sshkey.h misc.h log.h digest.h bitmap.h utf8.h krl.h +log.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h match.h +loginrec.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h sshkey.h hostfile.h ssh.h loginrec.h log.h ssherr.h atomicio.h packet.h dispatch.h canohost.h auth.h auth-pam.h audit.h sshbuf.h misc.h +logintest.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h loginrec.h +mac.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h digest.h hmac.h umac.h mac.h misc.h ssherr.h sshbuf.h openbsd-compat/openssl-compat.h +match.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h match.h misc.h +misc-agent.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h digest.h log.h ssherr.h misc.h pathnames.h ssh.h xmalloc.h +misc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h misc.h log.h ssherr.h ssh.h sshbuf.h +moduli.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +monitor.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/openssl-compat.h atomicio.h xmalloc.h ssh.h sshkey.h sshbuf.h hostfile.h auth.h auth-pam.h audit.h loginrec.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h +monitor.o: mac.h crypto_api.h dh.h packet.h dispatch.h auth-options.h sshpty.h channels.h session.h sshlogin.h canohost.h log.h ssherr.h misc.h servconf.h monitor.h monitor_wrap.h monitor_fdpass.h compat.h ssh2.h authfd.h match.h sk-api.h srclimit.h +monitor_fdpass.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h monitor_fdpass.h +monitor_wrap.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h sshbuf.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h crypto_api.h hostfile.h auth.h auth-pam.h audit.h loginrec.h auth-options.h +monitor_wrap.o: packet.h dispatch.h log.h ssherr.h monitor.h atomicio.h monitor_fdpass.h misc.h channels.h session.h servconf.h monitor_wrap.h srclimit.h +msg.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshbuf.h log.h ssherr.h atomicio.h msg.h misc.h +mux.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h log.h ssherr.h ssh.h ssh2.h misc.h match.h sshbuf.h channels.h packet.h dispatch.h monitor_fdpass.h sshpty.h readconf.h clientloop.h +nchan.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssh2.h sshbuf.h packet.h dispatch.h channels.h compat.h log.h ssherr.h +packet.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h compat.h ssh2.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h crypto_api.h digest.h log.h ssherr.h canohost.h misc.h packet.h dispatch.h sshbuf.h +platform-listen.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h misc.h +platform-misc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +platform-pledge.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +platform-tracing.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h +platform.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h misc.h servconf.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h +poly1305.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h poly1305.h +progressmeter.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h progressmeter.h atomicio.h misc.h utf8.h +readconf.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h pathnames.h log.h ssherr.h sshkey.h misc.h readconf.h match.h kex.h mac.h crypto_api.h myproposal.h digest.h +readconf.o: version.h +readpass.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h misc.h pathnames.h log.h ssherr.h ssh.h +rijndael.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h rijndael.h +sandbox-capsicum.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +sandbox-darwin.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +sandbox-null.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +sandbox-rlimit.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +sandbox-seccomp-filter.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +sandbox-solaris.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +scp.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h atomicio.h pathnames.h log.h ssherr.h misc.h progressmeter.h utf8.h sftp.h sftp-common.h sftp-client.h +servconf.o: groupaccess.h canohost.h packet.h dispatch.h hostfile.h auth.h auth-pam.h audit.h loginrec.h myproposal.h digest.h version.h +servconf.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h log.h ssherr.h sshbuf.h misc.h servconf.h pathnames.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h crypto_api.h match.h channels.h +serverloop.o: crypto_api.h hostfile.h auth.h auth-pam.h audit.h loginrec.h session.h auth-options.h serverloop.h +serverloop.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h packet.h dispatch.h sshbuf.h log.h ssherr.h misc.h servconf.h canohost.h sshpty.h channels.h ssh2.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h +session.o: hostfile.h auth.h auth-pam.h audit.h loginrec.h auth-options.h authfd.h pathnames.h log.h misc.h servconf.h sshlogin.h serverloop.h canohost.h session.h monitor_wrap.h sftp.h atomicio.h +session.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h ssh2.h sshpty.h packet.h dispatch.h sshbuf.h ssherr.h match.h uidswap.h channels.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h crypto_api.h +sftp-client.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssherr.h sshbuf.h log.h atomicio.h progressmeter.h misc.h utf8.h sftp.h sftp-common.h sftp-client.h +sftp-common.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssherr.h sshbuf.h log.h misc.h sftp.h sftp-common.h +sftp-glob.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h sftp.h sftp-common.h sftp-client.h +sftp-realpath.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +sftp-server-main.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h sftp.h misc.h xmalloc.h +sftp-server.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h atomicio.h xmalloc.h sshbuf.h ssherr.h log.h misc.h match.h uidswap.h sftp.h sftp-common.h +sftp-usergroup.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h xmalloc.h sftp-common.h sftp-client.h sftp-usergroup.h +sftp.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h log.h ssherr.h pathnames.h misc.h utf8.h sftp.h sshbuf.h sftp-common.h sftp-client.h sftp-usergroup.h +sk-usbhid.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +sntrup761.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +srclimit.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h addr.h canohost.h log.h ssherr.h misc.h srclimit.h xmalloc.h servconf.h match.h +ssh-add.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h log.h ssherr.h sshkey.h sshbuf.h authfd.h authfile.h pathnames.h misc.h digest.h ssh-sk.h sk-api.h hostfile.h +ssh-agent.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h ssh2.h sshbuf.h sshkey.h authfd.h log.h ssherr.h misc.h digest.h match.h msg.h pathnames.h ssh-pkcs11.h sk-api.h myproposal.h +ssh-ecdsa-sk.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/openssl-compat.h sshbuf.h ssherr.h digest.h sshkey.h +ssh-ecdsa.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +ssh-ed25519-sk.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h crypto_api.h log.h ssherr.h sshbuf.h sshkey.h digest.h +ssh-ed25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h crypto_api.h log.h ssherr.h sshbuf.h sshkey.h ssh-keygen.o: cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h -ssh-keygen.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h sshkey.h authfile.h sshbuf.h pathnames.h log.h ssherr.h misc.h match.h hostfile.h dns.h ssh.h ssh2.h ssh-pkcs11.h atomicio.h krl.h digest.h utf8.h authfd.h sshsig.h ssh-sk.h sk-api.h cipher.h -ssh-keyscan.o: dispatch.h log.h ssherr.h atomicio.h misc.h hostfile.h ssh_api.h ssh2.h dns.h addr.h -ssh-keyscan.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h sshbuf.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h digest.h kex.h mac.h crypto_api.h compat.h myproposal.h packet.h -ssh-keysign.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h log.h ssherr.h sshkey.h ssh.h ssh2.h misc.h sshbuf.h authfile.h msg.h canohost.h pathnames.h readconf.h uidswap.h -ssh-pkcs11-client.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -ssh-pkcs11-helper.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h sshbuf.h log.h ssherr.h misc.h sshkey.h authfd.h ssh-pkcs11.h -ssh-pkcs11.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h sshkey.h -ssh-rsa.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -ssh-sk-client.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h sshbuf.h sshkey.h msg.h digest.h pathnames.h ssh-sk.h misc.h -ssh-sk-helper.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h log.h ssherr.h sshkey.h authfd.h misc.h sshbuf.h msg.h uidswap.h ssh-sk.h -ssh-sk.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -ssh-xmss.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -ssh.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/openssl-compat.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h canohost.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h packet.h dispatch.h sshbuf.h channels.h -ssh.o: sshkey.h authfd.h authfile.h pathnames.h clientloop.h log.h ssherr.h misc.h readconf.h sshconnect.h kex.h mac.h crypto_api.h sshpty.h match.h msg.h version.h myproposal.h utf8.h -ssh_api.o: authfile.h dh.h misc.h version.h myproposal.h sshbuf.h openbsd-compat/openssl-compat.h -ssh_api.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssh_api.h openbsd-compat/sys-queue.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h crypto_api.h ssh.h ssh2.h packet.h dispatch.h compat.h log.h ssherr.h -sshbuf-getput-basic.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h -sshbuf-getput-crypto.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -sshbuf-io.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h atomicio.h -sshbuf-misc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h -sshbuf.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h misc.h -sshconnect.o: authfd.h kex.h mac.h crypto_api.h -sshconnect.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h hostfile.h ssh.h sshbuf.h packet.h openbsd-compat/sys-queue.h dispatch.h sshkey.h sshconnect.h log.h ssherr.h match.h misc.h readconf.h atomicio.h dns.h monitor_fdpass.h ssh2.h version.h authfile.h -sshconnect2.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h sshbuf.h packet.h dispatch.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h crypto_api.h -sshconnect2.o: sshconnect.h authfile.h dh.h authfd.h log.h ssherr.h misc.h readconf.h match.h canohost.h msg.h pathnames.h uidswap.h hostfile.h utf8.h ssh-sk.h sk-api.h -sshd-session.o: chacha.h poly1305.h cipher-aesctr.h rijndael.h digest.h sshkey.h kex.h mac.h crypto_api.h authfile.h pathnames.h atomicio.h canohost.h hostfile.h auth.h auth-pam.h audit.h loginrec.h authfd.h msg.h channels.h session.h monitor.h monitor_wrap.h ssh-sandbox.h auth-options.h version.h sk-api.h srclimit.h dh.h -sshd-session.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ./openbsd-compat/sys-tree.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h sshpty.h packet.h dispatch.h log.h ssherr.h sshbuf.h misc.h match.h servconf.h uidswap.h compat.h cipher.h cipher-chachapoly.h -sshd.o: audit.h loginrec.h authfd.h msg.h version.h sk-api.h addr.h srclimit.h -sshd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ./openbsd-compat/sys-tree.h openbsd-compat/sys-queue.h xmalloc.h ssh.h sshpty.h log.h ssherr.h sshbuf.h misc.h servconf.h compat.h digest.h sshkey.h authfile.h pathnames.h canohost.h hostfile.h auth.h auth-pam.h +ssh-keygen.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h sshkey.h authfile.h sshbuf.h pathnames.h log.h ssherr.h misc.h match.h hostfile.h dns.h ssh.h ssh2.h atomicio.h krl.h digest.h utf8.h authfd.h sshsig.h ssh-sk.h sk-api.h cipher.h +ssh-keyscan.o: atomicio.h misc.h hostfile.h ssh_api.h ssh2.h dns.h addr.h +ssh-keyscan.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h sshbuf.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h digest.h kex.h mac.h crypto_api.h compat.h myproposal.h packet.h dispatch.h log.h ssherr.h +ssh-keysign.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h log.h ssherr.h sshkey.h ssh.h ssh2.h misc.h sshbuf.h authfile.h msg.h canohost.h pathnames.h readconf.h uidswap.h +ssh-pkcs11-client.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h pathnames.h xmalloc.h sshbuf.h log.h ssherr.h misc.h sshkey.h authfd.h atomicio.h ssh-pkcs11.h +ssh-pkcs11-helper.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h sshbuf.h log.h ssherr.h misc.h sshkey.h authfd.h ssh-pkcs11.h +ssh-pkcs11.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h sshkey.h ssh-pkcs11.h +ssh-rsa.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +ssh-sk-client.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h sshbuf.h sshkey.h msg.h pathnames.h ssh-sk.h misc.h +ssh-sk-helper.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h log.h ssherr.h sshkey.h authfd.h misc.h sshbuf.h msg.h uidswap.h ssh-sk.h ssh-pkcs11.h +ssh-sk.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +ssh.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/openssl-compat.h xmalloc.h ssh.h ssh2.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h packet.h dispatch.h sshbuf.h channels.h sshkey.h authfd.h authfile.h +ssh.o: pathnames.h clientloop.h log.h ssherr.h misc.h readconf.h sshconnect.h kex.h mac.h crypto_api.h match.h version.h utf8.h +ssh_api.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssh_api.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h crypto_api.h ssh.h ssh2.h packet.h dispatch.h compat.h log.h ssherr.h authfile.h dh.h misc.h version.h +ssh_api.o: myproposal.h sshbuf.h openbsd-compat/openssl-compat.h +sshbuf-getput-basic.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h +sshbuf-getput-crypto.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +sshbuf-io.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h atomicio.h +sshbuf-misc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h +sshbuf.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h misc.h +sshconnect.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h hostfile.h ssh.h compat.h packet.h dispatch.h sshkey.h sshconnect.h log.h ssherr.h match.h misc.h readconf.h dns.h monitor_fdpass.h authfile.h authfd.h kex.h mac.h crypto_api.h +sshconnect2.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h ssh2.h sshbuf.h packet.h dispatch.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h crypto_api.h sshconnect.h authfile.h authfd.h +sshconnect2.o: log.h ssherr.h misc.h readconf.h match.h canohost.h msg.h pathnames.h hostfile.h utf8.h ssh-sk.h sk-api.h +sshd-auth.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h ssh2.h sshpty.h packet.h dispatch.h log.h ssherr.h sshbuf.h misc.h match.h servconf.h uidswap.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h digest.h +sshd-auth.o: sshkey.h kex.h mac.h crypto_api.h authfile.h pathnames.h atomicio.h canohost.h hostfile.h auth.h auth-pam.h audit.h loginrec.h authfd.h msg.h channels.h session.h monitor.h monitor_wrap.h auth-options.h version.h sk-api.h srclimit.h ssh-sandbox.h dh.h +sshd-session.o: digest.h sshkey.h kex.h mac.h crypto_api.h authfile.h pathnames.h atomicio.h canohost.h hostfile.h auth.h auth-pam.h audit.h loginrec.h authfd.h msg.h channels.h session.h monitor.h monitor_wrap.h auth-options.h version.h sk-api.h srclimit.h dh.h +sshd-session.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h ssh2.h sshpty.h packet.h dispatch.h log.h ssherr.h sshbuf.h misc.h match.h servconf.h uidswap.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h +sshd.o: addr.h srclimit.h atomicio.h monitor_wrap.h +sshd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h sshpty.h log.h ssherr.h sshbuf.h misc.h servconf.h compat.h digest.h sshkey.h authfile.h pathnames.h canohost.h hostfile.h auth.h auth-pam.h audit.h loginrec.h authfd.h msg.h version.h sk-api.h +ssherr-libcrypto.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h +ssherr-nolibcrypto.o: ssherr.h ssherr.o: ssherr.h -sshkey-xmss.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -sshkey.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h crypto_api.h ssh2.h ssherr.h misc.h sshbuf.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h digest.h sshkey.h match.h ssh-sk.h openbsd-compat/openssl-compat.h -sshlogin.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshlogin.h ssherr.h loginrec.h log.h sshbuf.h misc.h servconf.h openbsd-compat/sys-queue.h -sshpty.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshpty.h log.h ssherr.h misc.h -sshsig.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h authfd.h authfile.h log.h ssherr.h misc.h sshbuf.h sshsig.h sshkey.h match.h digest.h -sshtty.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshpty.h -ttymodes.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h packet.h openbsd-compat/sys-queue.h dispatch.h log.h ssherr.h compat.h sshbuf.h ttymodes.h -uidswap.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h uidswap.h xmalloc.h -umac.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h umac.h misc.h rijndael.h -umac128.o: umac.c includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h umac.h misc.h rijndael.h -utf8.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h utf8.h -xmalloc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h log.h ssherr.h -xmss_commons.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -xmss_fast.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -xmss_hash.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -xmss_hash_address.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -xmss_wots.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +sshkey.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h crypto_api.h ssh2.h ssherr.h misc.h sshbuf.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h digest.h sshkey.h match.h ssh-sk.h ssh-pkcs11.h openbsd-compat/openssl-compat.h +sshlogin.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshlogin.h ssherr.h loginrec.h log.h sshbuf.h misc.h servconf.h +sshpty.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshpty.h log.h ssherr.h misc.h +sshsig.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h authfd.h authfile.h log.h ssherr.h misc.h sshbuf.h sshsig.h sshkey.h match.h digest.h +sshtty.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshpty.h +ttymodes.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h packet.h dispatch.h log.h ssherr.h compat.h sshbuf.h ttymodes.h +uidswap.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h uidswap.h xmalloc.h +umac.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h umac.h misc.h rijndael.h +umac128.o: umac.c includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h umac.h misc.h rijndael.h +utf8.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h utf8.h +xmalloc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/bsd-sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h log.h ssherr.h diff --git a/.git_allowed_signers b/.git_allowed_signers index 2a5fdc6..04fe425 100644 --- a/.git_allowed_signers +++ b/.git_allowed_signers @@ -1,7 +1,11 @@ -dtucker@dtucker.net ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKecyjh9aNmD4rb8WblA8v91JjRb0Cd2JtkzqxcggGeG +dtucker@dtucker.net valid-before="20241206" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKecyjh9aNmD4rb8WblA8v91JjRb0Cd2JtkzqxcggGeG dtucker@dtucker.net sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBDV81zWQ1+XVfWH5z4L4klDQ/z/6l2GLphfSTX/Rmq6kL5H8mkfzUlryxLlkN8cD9srtVJBAmwJWfJBNsCo958YAAAAEc3NoOg== +dtucker@dtucker.net sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIElSYahCw60CGct39Eg9EY8OLV9Ppr7tsudvSiMyNHOhAAAABHNzaDo= djm@mindrot.org sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBLnJo3ZVDENYZGXm5uO9lU7b0iDFq5gHpTu1MaHPWTEfPdvw+AjFQQ/q5YizuMJkXGsMdYmblJEJZYHpm9IS7ZkAAAAEc3NoOg== djm@mindrot.org sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBJoAXBTQalfg+kC5wy1vE7HkIHtVnmV6AUuuIo9KQ1P+70juHwvsFKpsGaqQbrHJkTVgYDGVP02XHj8+Fb18yBIAAAAEc3NoOg== djm@mindrot.org sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBH+z1I48s6ydOhP5SJmI02zVCLf0K15B+UMHgoTIKVfUIv5oDoVX7e9f+7QiRmTeEOdZfQydiaVqsfi7qPSve+0AAAAEc3NoOg== djm@mindrot.org sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBPM4BmUg/fMnsl42JwktTekk/mB8Be3M+yK2ayg6lqYsqEri8yhRx84gey51OHKVk1TwlGbJjcMHI4URreDBEMQAAAAEc3NoOg== + +tim@multitalents.net ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC/L8E1DfiZ9cHzygqx0IzRCSAlmh4tXH7mZPwWZEY1L + diff --git a/.github/ci-status.md b/.github/ci-status.md new file mode 100644 index 0000000..00a1db0 --- /dev/null +++ b/.github/ci-status.md @@ -0,0 +1,27 @@ +master : +[![C/C++ CI](../../../actions/workflows/c-cpp.yml/badge.svg)](../../../actions/workflows/c-cpp.yml?query=branch:master) +[![VM CI](../../../actions/workflows/vm.yml/badge.svg)](../../../actions/workflows/vm.yml?query=branch:master) +[![C/C++ CI self-hosted](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml/badge.svg)](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml?query=branch:master) +[![Upstream self-hosted](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/upstream.yml/badge.svg)](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/upstream.yml?query=branch:master) +[![CIFuzz](../../../actions/workflows/cifuzz.yml/badge.svg)](../../../actions/workflows/cifuzz.yml) +[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/openssh.svg)](https://issues.oss-fuzz.com/issues?q="Project:+openssh"+is:open) +[![Coverity Status](https://scan.coverity.com/projects/21341/badge.svg)](https://scan.coverity.com/projects/openssh-portable) +
+ +10.2 : +[![C/C++ CI](../../../actions/workflows/c-cpp.yml/badge.svg?branch=V_10_2)](../../../actions/workflows/c-cpp.yml?query=branch:V_10_2) +[![VM CI](../../../actions/workflows/vm.yml/badge.svg?branch=V_10_2)](../../../actions/workflows/vm.yml?query=branch:V_10_2) +[![C/C++ CI self-hosted](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml/badge.svg?branch=V_10_2)](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml?query=branch:V_10_2) + +10.1 : +[![C/C++ CI](../../../actions/workflows/c-cpp.yml/badge.svg?branch=V_10_1)](../../../actions/workflows/c-cpp.yml?query=branch:V_10_1) +[![VM CI](../../../actions/workflows/vm.yml/badge.svg?branch=V_10_1)](../../../actions/workflows/vm.yml?query=branch:V_10_1) +[![C/C++ CI self-hosted](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml/badge.svg?branch=V_10_1)](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml?query=branch:V_10_1) + +10.0 : +[![C/C++ CI](../../../actions/workflows/c-cpp.yml/badge.svg?branch=V_10_0)](../../../actions/workflows/c-cpp.yml?query=branch:V_10_0) +[![C/C++ CI self-hosted](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml/badge.svg?branch=V_10_0)](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml?query=branch:V_10_0) + +9.9 : +[![C/C++ CI](../../../actions/workflows/c-cpp.yml/badge.svg?branch=V_9_9)](../../../actions/workflows/c-cpp.yml?query=branch:V_9_9) +[![C/C++ CI self-hosted](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml/badge.svg?branch=V_9_9)](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml?query=branch:V_9_9) diff --git a/.github/configs b/.github/configs new file mode 100755 index 0000000..9ad2439 --- /dev/null +++ b/.github/configs @@ -0,0 +1,418 @@ +#!/bin/sh +# +# usage: configs vmname test_config (or '' for default) +# +# Sets the following variables: +# CONFIGFLAGS options to ./configure +# SSHD_CONFOPTS sshd_config options +# TEST_TARGET make target used when testing. defaults to "tests". +# LTESTS + +config=$1 +if [ "$config" = "" ]; then + config="default" +fi + +if [ ! -z "${LTESTS}" ]; then + OVERRIDE_LTESTS="${LTESTS}" +fi + +unset CC CFLAGS CPPFLAGS LDFLAGS LTESTS SUDO + +TEST_TARGET="tests compat-tests" +LTESTS="" +SKIP_LTESTS="" +SUDO=sudo # run with sudo by default +TEST_SSH_UNSAFE_PERMISSIONS=1 +# Stop on first test failure to minimize logs +TEST_SSH_FAIL_FATAL=yes + +CONFIGFLAGS="" +LIBCRYPTOFLAGS="" + +case "$config" in + default|sol64) + ;; + c89) + # If we don't have LLONG_MAX, configure will figure out that it can + # get it by setting -std=gnu99, at which point we won't be testing + # C89 any more. To avoid this, feed it in via CFLAGS. + llong_max=`gcc -E -dM - /dev/null)" ]; then + REGRESS_INTEROP_PUTTY=yes + export REGRESS_INTEROP_PUTTY +fi + +if [ ! -z "${OVERRIDE_LTESTS}" ]; then + echo >&2 "Overriding LTESTS, was '${LTESTS}', now '${OVERRIDE_LTESTS}'" + LTESTS="${OVERRIDE_LTESTS}" +fi + +export CC CFLAGS CPPFLAGS LDFLAGS LTESTS SUDO +export TEST_TARGET TEST_SSH_UNSAFE_PERMISSIONS TEST_SSH_FAIL_FATAL diff --git a/.github/configure.sh b/.github/configure.sh new file mode 100755 index 0000000..bd00377 --- /dev/null +++ b/.github/configure.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +. .github/configs $1 + +printf "$ " + +if [ "x$CC" != "x" ]; then + printf "CC='$CC' " +fi +if [ "x$CFLAGS" != "x" ]; then + printf "CFLAGS='$CFLAGS' " +fi +if [ "x$CPPFLAGS" != "x" ]; then + printf "CPPFLAGS='$CPPFLAGS' " +fi +if [ "x$LDFLAGS" != "x" ]; then + printf "LDFLAGS='$LDFLAGS' " +fi + +echo ./configure ${CONFIGFLAGS} +./configure ${CONFIGFLAGS} 2>&1 diff --git a/.github/install_libcrypto.sh b/.github/install_libcrypto.sh new file mode 100755 index 0000000..d1aa234 --- /dev/null +++ b/.github/install_libcrypto.sh @@ -0,0 +1,75 @@ +#!/bin/sh +# +# Install specified libcrypto. +# -a : install version for ABI compatibility test. +# -n : dry run, don't actually build and install. +# +# Usage: $0 [-a] [-n] openssl-$branch/tag destdir [config options] + +set -e + +bincompat_test="" +dryrun="" +while [ "$1" = "-a" ] || [ "$1" = "-n" ]; do + if [ "$1" = "-a" ]; then + abi_compat_test=y + elif [ "$1" = "-n" ]; then + dryrun="echo dryrun:" + fi + shift +done + +ver="$1" +destdir="$2" +opts="$3" + +if [ -z "${ver}" ] || [ -z "${destdir}" ]; then + echo tag/branch and destdir required + exit 1 +fi + +set -x + +if [ ! -d ${HOME}/openssl ]; then + cd ${HOME} + git clone https://github.com/openssl/openssl.git + cd ${HOME}/openssl + git fetch --all +fi +cd ${HOME}/openssl + +if [ "${abi_compat_test}" = "y" ]; then + echo selecting ABI test release/branch for ${ver} + case "${ver}" in + openssl-3.6) + ver=openssl-3.0.0 + echo "selecting older release ${ver}" + ;; + openssl-3.[012345]) + major=$(echo ${ver} | cut -f1 -d.) + minor=$(echo ${ver} | cut -f2 -d.) + ver="${major}.$((${minor} + 1))" + echo selecting next release branch ${ver} + ;; + openssl-3.*.*) + major=$(echo ${ver} | cut -f1 -d.) + minor=$(echo ${ver} | cut -f2 -d.) + patch=$(echo ${ver} | cut -f3 -d.) + ver="${major}.${minor}.$((${patch} + 1))" + echo checking for release tag ${ver} + if git tag | grep -q "^${ver}\$"; then + echo selected next patch release ${ver} + else + ver="${major}.${minor}" + echo not found, selecting release branch ${ver} + fi + ;; + esac +fi + +git checkout ${ver} +make clean >/dev/null 2>&1 || true +${dryrun} ./config no-threads shared ${opts} --prefix=${destdir} \ + -Wl,-rpath,${destdir}/lib64 +${dryrun} make -j4 +${dryrun} sudo make install_sw diff --git a/.github/install_putty.sh b/.github/install_putty.sh new file mode 100755 index 0000000..6d6d0ad --- /dev/null +++ b/.github/install_putty.sh @@ -0,0 +1,37 @@ +#!/bin/sh + +ver="$1" + +echo +echo -------------------------------------- +echo Installing PuTTY version ${ver} +echo -------------------------------------- + +cd /tmp + +case "${ver}" in +snapshot) + tarball=putty.tar.gz + url=https://tartarus.org/~simon/putty-snapshots/${tarball} + ;; +*) + tarball=putty-${ver}.tar.gz + url=https://the.earth.li/~sgtatham/putty/${ver}/${tarball} + ;; +esac + +if [ ! -f ${tarball} ]; then + wget -q ${url} +fi + +mkdir -p /tmp/puttybuild +cd /tmp/puttybuild + +tar xfz /tmp/${tarball} && cd putty-* +if [ -f CMakeLists.txt ]; then + cmake . && cmake --build . -j4 && sudo cmake --build . --target install +else + ./configure && make -j4 && sudo make install +fi +sudo rm -rf /tmp/puttybuild +/usr/local/bin/plink -V diff --git a/.github/run_test.sh b/.github/run_test.sh new file mode 100755 index 0000000..c67d007 --- /dev/null +++ b/.github/run_test.sh @@ -0,0 +1,66 @@ +#!/bin/sh + +. .github/configs $1 + +[ -z "${SUDO}" ] || ${SUDO} mkdir -p /var/empty + +set -ex + +# If we want to test hostbased auth, set up the host for it. +if [ ! -z "$SUDO" ] && [ ! -z "$TEST_SSH_HOSTBASED_AUTH" ]; then + sshconf=/usr/local/etc + $SUDO mkdir -p "${sshconf}" + hostname | $SUDO tee $sshconf/shosts.equiv >/dev/null + echo "EnableSSHKeysign yes" | $SUDO tee $sshconf/ssh_config >/dev/null + $SUDO mkdir -p $sshconf + $SUDO make install + for key in $sshconf/ssh_host*key*.pub; do + echo `hostname` `cat $key` | \ + $SUDO tee -a $sshconf/ssh_known_hosts >/dev/null + done +fi + +env="" +if [ ! -z "${SUDO}" ]; then + env="${env} SUDO=${SUDO}" +fi +if [ ! -z "${TCMALLOC_STACKTRACE_METHOD}" ]; then + env="${env} TCMALLOC_STACKTRACE_METHOD=${TCMALLOC_STACKTRACE_METHOD}" +fi +if [ ! -z "${TEST_SSH_SSHD_ENV}" ]; then + env="${env} TEST_SSH_SSHD_ENV=${TEST_SSH_SSHD_ENV}" +fi +if [ ! -z "${env}" ]; then + env="env${env}" +fi + +if [ "$1" = "putty-versions" ]; then + for ver in 0.71 0.72 0.73 0.74 0.75 0.76 0.77 0.78 0.79 0.80 \ + 0.81 0.82 0.83 snapshot; do + .github/install_putty.sh "${ver}" + ${env} make ${TEST_TARGET} \ + SKIP_LTESTS="${SKIP_LTESTS}" LTESTS="${LTESTS}" + done + + exit 0 +fi + +if [ -z "${LTESTS}" ]; then + ${env} make ${TEST_TARGET} SKIP_LTESTS="${SKIP_LTESTS}" +else + ${env} make ${TEST_TARGET} SKIP_LTESTS="${SKIP_LTESTS}" LTESTS="${LTESTS}" +fi + +# Activate kbdint regression test for PAM +if echo "${SSHD_CONFOPTS}" | grep -i usepam >/dev/null && [ -f regress/password ]; then + cp regress/password regress/kbdintpw +fi + +if [ ! -z "${SSHD_CONFOPTS}" ]; then + echo "rerunning t-exec with TEST_SSH_SSHD_CONFOPTS='${SSHD_CONFOPTS}'" + if [ -z "${LTESTS}" ]; then + ${env} make t-exec SKIP_LTESTS="${SKIP_LTESTS}" TEST_SSH_SSHD_CONFOPTS="${SSHD_CONFOPTS}" + else + ${env} make t-exec SKIP_LTESTS="${SKIP_LTESTS}" LTESTS="${LTESTS}" TEST_SSH_SSHD_CONFOPTS="${SSHD_CONFOPTS}" + fi +fi diff --git a/.github/setup_ci.sh b/.github/setup_ci.sh new file mode 100755 index 0000000..e1b3dcf --- /dev/null +++ b/.github/setup_ci.sh @@ -0,0 +1,295 @@ +#!/bin/sh + +config="$1" +target="$2" + +PACKAGES="tmux" + +echo Running as: +id + +echo Environment: +set + + . .github/configs ${config} + +host=`./config.guess` +echo "config.guess: $host" +case "$host" in +*cygwin) + PACKAGER=setup + echo Setting CYGWIN system environment variable. + setx CYGWIN "winsymlinks:native" + echo Removing extended ACLs so umask works as expected. + set -x + setfacl -b . regress + icacls regress /c /t /q /Inheritance:d + icacls regress /c /t /q /Grant ${USERNAME}:F + icacls regress /c /t /q /Remove:g "Authenticated Users" \ + BUILTIN\\Administrators BUILTIN Everyone System Users + takeown /F regress + icacls regress + set +x + PACKAGES="$PACKAGES,autoconf,automake,cygwin-devel,gcc-core" + PACKAGES="$PACKAGES,make,openssl,libssl-devel,zlib-devel" + ;; +*-darwin*) + PACKAGER=brew + PACKAGES="automake" + ;; +*) + PACKAGER=apt +esac + +TARGETS=${config} + +INSTALL_FIDO_PPA="no" +export DEBIAN_FRONTEND=noninteractive + +set -e + +if [ -x "`which lsb_release 2>&1`" ]; then + lsb_release -a +fi + +if [ ! -z "$SUDO" ]; then + # Ubuntu 22.04 defaults to private home dirs which prevent the + # agent-getpeerid test from running ssh-add as nobody. See + # https://github.com/actions/runner-images/issues/6106 + if ! "$SUDO" -u nobody test -x ~; then + echo ~ is not executable by nobody, adding perms. + chmod go+x ~ + fi + # Some of the Mac OS X runners don't have a nopasswd sudo rule. Regular + # sudo still works, but sudo -u doesn't. Restore the sudo rule. + if ! "$SUDO" grep -E 'runner.*NOPASSWD' /etc/passwd >/dev/null; then + echo "Restoring runner nopasswd rule to sudoers." + echo 'runner ALL=(ALL) NOPASSWD: ALL' |$SUDO tee -a /etc/sudoers + fi + if ! "$SUDO" -u nobody -S test -x ~ regress/password + pw=$(tr -d '\n' Settings -> +# Security -> Actions -> Variables) to restrict the tests that are run. +# The supported variables are: +# +# RUN_ONLY_TARGET_CONFIG: Run only the single matching target and config, +# separated by spaces, eg "ubuntu-latest default". All other tests will +# fail immediately. +# +# LTESTS: Override the set of tests run. + +on: + push: + paths: [ '**.c', '**.h', '**.m4', '**.sh', '**/Makefile.in', 'configure.ac', '.github/configs', '.github/*.sh', '.github/workflows/c-cpp.yml' ] + pull_request: + paths: [ '**.c', '**.h', '**.m4', '**.sh', '**/Makefile.in', 'configure.ac', '.github/configs', '.github/*.sh', '.github/workflows/c-cpp.yml' ] + +jobs: + ci: + name: "${{ matrix.target }} ${{ matrix.config }}" + if: github.repository != 'openssh/openssh-portable-selfhosted' + strategy: + fail-fast: false + matrix: + # First we test all OSes in the default configuration. + target: + - ubuntu-22.04 + - ubuntu-latest + - ubuntu-22.04-arm + - ubuntu-24.04-arm + - macos-14 + - macos-15 + - macos-15-intel + - windows-2022 + - windows-2025 + config: [default] + # Then we include any extra configs we want to test for specific VMs. + # Valgrind slows things down quite a bit, so start them first. + include: + - { target: windows-2022, config: cygwin-release } + - { target: windows-2025, config: cygwin-release } + - { target: ubuntu-22.04, config: c89 } + - { target: ubuntu-22.04, config: clang-11 } + - { target: ubuntu-22.04, config: clang-12-Werror } + - { target: ubuntu-22.04, config: clang-14 } + - { target: ubuntu-22.04, config: clang-sanitize-address } + - { target: ubuntu-22.04, config: clang-sanitize-undefined } + - { target: ubuntu-22.04, config: gcc-9 } + - { target: ubuntu-22.04, config: gcc-11-Werror } + - { target: ubuntu-22.04, config: gcc-12-Werror } + - { target: ubuntu-22.04, config: gcc-sanitize-address } + - { target: ubuntu-22.04, config: gcc-sanitize-undefined } + - { target: ubuntu-22.04, config: hardenedmalloc } + - { target: ubuntu-22.04, config: heimdal } + - { target: ubuntu-22.04, config: kitchensink } + - { target: ubuntu-22.04, config: krb5 } + - { target: ubuntu-22.04, config: libedit } + - { target: ubuntu-22.04, config: pam } + - { target: ubuntu-22.04, config: selinux } + - { target: ubuntu-22.04, config: sk } + - { target: ubuntu-22.04, config: valgrind-1 } + - { target: ubuntu-22.04, config: valgrind-2 } + - { target: ubuntu-22.04, config: valgrind-3 } + - { target: ubuntu-22.04, config: valgrind-4 } + - { target: ubuntu-22.04, config: valgrind-pam-1 } + - { target: ubuntu-22.04, config: valgrind-unit } + - { target: ubuntu-22.04, config: without-openssl } + - { target: ubuntu-latest, config: gcc-14 } + - { target: ubuntu-latest, config: clang-15 } + - { target: ubuntu-latest, config: clang-19 } + - { target: ubuntu-latest, config: boringssl } + - { target: ubuntu-latest, config: aws-lc } + - { target: ubuntu-latest, config: libressl-master } + - { target: ubuntu-latest, config: libressl-3.2.7 } + - { target: ubuntu-latest, config: libressl-3.3.6 } + - { target: ubuntu-latest, config: libressl-3.4.3 } + - { target: ubuntu-latest, config: libressl-3.5.4 } + - { target: ubuntu-latest, config: libressl-3.6.3 } + - { target: ubuntu-latest, config: libressl-3.7.3 } + - { target: ubuntu-latest, config: libressl-3.8.4 } + - { target: ubuntu-latest, config: libressl-3.9.2 } + - { target: ubuntu-latest, config: libressl-4.0.1 } + - { target: ubuntu-latest, config: libressl-4.1.1 } + - { target: ubuntu-latest, config: libressl-4.2.0 } + - { target: ubuntu-latest, config: openssl-master } + - { target: ubuntu-latest, config: openssl-noec } + - { target: ubuntu-latest, config: openssl-1.1.1 } + - { target: ubuntu-latest, config: openssl-1.1.1t } + - { target: ubuntu-latest, config: openssl-1.1.1w } + - { target: ubuntu-latest, config: openssl-3.0.0 } + - { target: ubuntu-latest, config: openssl-3.0.18 } + - { target: ubuntu-latest, config: openssl-3.1.0 } + - { target: ubuntu-latest, config: openssl-3.1.8 } + - { target: ubuntu-latest, config: openssl-3.2.6 } + - { target: ubuntu-latest, config: openssl-3.3.5 } + - { target: ubuntu-latest, config: openssl-3.4.0 } + - { target: ubuntu-latest, config: openssl-3.4.3 } + - { target: ubuntu-latest, config: openssl-3.5.0 } + - { target: ubuntu-latest, config: openssl-3.5.3 } # keep + - { target: ubuntu-latest, config: openssl-3.5.4 } + - { target: ubuntu-latest, config: openssl-1.1.1_stable } + - { target: ubuntu-latest, config: openssl-3.0 } # stable branch + - { target: ubuntu-latest, config: openssl-3.1 } # stable branch + - { target: ubuntu-latest, config: openssl-3.2 } # stable branch + - { target: ubuntu-latest, config: openssl-3.3 } # stable branch + - { target: ubuntu-latest, config: openssl-3.4 } # stable branch + - { target: ubuntu-latest, config: openssl-3.5 } # stable branch + - { target: ubuntu-latest, config: openssl-3.6 } # stable branch + - { target: ubuntu-latest, config: putty-versions } + - { target: ubuntu-latest, config: zlib-develop } + - { target: ubuntu-latest, config: tcmalloc } + - { target: ubuntu-latest, config: musl } + - { target: ubuntu-22.04-arm, config: kitchensink } + - { target: ubuntu-24.04-arm, config: kitchensink } + - { target: macos-14, config: pam } + - { target: macos-15, config: pam } + runs-on: ${{ matrix.target }} + env: + EPHEMERAL_VM: yes + steps: + - name: check RUN_ONLY_TARGET_CONFIG + if: vars.RUN_ONLY_TARGET_CONFIG != '' + run: sh -c 'if [ "${{ vars.RUN_ONLY_TARGET_CONFIG }}" != "${{ matrix.target }} ${{matrix.config }}" ]; then exit 1; else exit 0; fi' + - name: set cygwin git params + if: ${{ startsWith(matrix.target, 'windows') }} + run: git config --global core.autocrlf input + - name: install cygwin + id: cygwin_install + if: ${{ startsWith(matrix.target, 'windows') }} + uses: cygwin/cygwin-install-action@master + env: + CYGWIN: "winsymlinks:native" + - uses: actions/checkout@main + - name: setup CI system + run: sh ./.github/setup_ci.sh ${{ matrix.config }} ${{ matrix.target }} + env: + CYGWIN_SETUP: ${{ steps.cygwin_install.outputs.setup }} + - name: autoreconf + run: sh -c autoreconf + - name: configure + run: sh ./.github/configure.sh ${{ matrix.config }} + - name: save config + uses: actions/upload-artifact@main + with: + name: ${{ matrix.target }}-${{ matrix.config }}-config + path: config.h + - name: make clean + run: make clean + - name: make + run: make + - name: make tests + run: sh ./.github/run_test.sh ${{ matrix.config }} + env: + TEST_SSH_UNSAFE_PERMISSIONS: 1 + TEST_SSH_HOSTBASED_AUTH: yes + LTESTS: ${{ vars.LTESTS }} + - name: test OpenSSL3 ABI compatibility + if: ${{ startsWith(matrix.config, 'openssl-3') }} + run: | + sh .github/install_libcrypto.sh -a ${{ matrix.config }} /opt/openssl + sh .github/run_test.sh ${{ matrix.config }} + - name: show logs + if: failure() + run: for i in regress/failed*.log; do echo ====; echo logfile $i; echo =====; cat $i; done + - name: chown logs + if: failure() + run: test -x "$(which sudo 2>&1)" && sudo chown -R "${LOGNAME}" regress + - name: save logs + if: failure() + uses: actions/upload-artifact@main + with: + name: ${{ matrix.target }}-${{ matrix.config }}-logs + path: | + config.h + config.log + regress/ diff --git a/.github/workflows/call-auto-tag.yml b/.github/workflows/call-auto-tag.yml deleted file mode 100644 index 3f9b471..0000000 --- a/.github/workflows/call-auto-tag.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: auto tag - -on: - pull_request_target: - types: [opened, synchronize, closed] - paths: - - "debian/changelog" - -concurrency: - group: ${{ github.workflow }}-pull/${{ github.event.number }} - cancel-in-progress: true - -jobs: - auto_tag: - uses: deepin-community/.github/.github/workflows/auto-tag.yml@master - secrets: - APP_PRIVATE_KEY: ${{ secrets.APP_PRIVATE_KEY }} diff --git a/.github/workflows/call-build-deb.yml b/.github/workflows/call-build-deb.yml deleted file mode 100644 index dcbe2ab..0000000 --- a/.github/workflows/call-build-deb.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Call build-deb -on: - pull_request_target: - paths-ignore: - - ".github/workflows/**" - types: [ opened, closed, synchronize ] - -concurrency: - group: ${{ github.workflow }}-pull/${{ github.event.number }} - cancel-in-progress: true - -jobs: - check_job: - if: github.event.action != 'closed' || github.event.pull_request.merged - uses: deepin-community/.github/.github/workflows/build-deb.yml@master - secrets: - BridgeToken: ${{ secrets.BridgeToken }} diff --git a/.github/workflows/call-build-tag.yml b/.github/workflows/call-build-tag.yml deleted file mode 100644 index d0a591a..0000000 --- a/.github/workflows/call-build-tag.yml +++ /dev/null @@ -1,14 +0,0 @@ -name: tag build -on: - push: - tags: "*" - -concurrency: - group: ${{ github.workflow }} - cancel-in-progress: true - -jobs: - build: - uses: deepin-community/.github/.github/workflows/build-tag.yml@master - secrets: - BridgeToken: ${{ secrets.BridgeToken }} diff --git a/.github/workflows/call-chatOps.yml b/.github/workflows/call-chatOps.yml deleted file mode 100644 index 83ef38c..0000000 --- a/.github/workflows/call-chatOps.yml +++ /dev/null @@ -1,9 +0,0 @@ -name: chatOps -on: - issue_comment: - types: [created] - -jobs: - chatopt: - uses: deepin-community/.github/.github/workflows/chatOps.yml@master - secrets: inherit diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml new file mode 100644 index 0000000..ab8b1c6 --- /dev/null +++ b/.github/workflows/cifuzz.yml @@ -0,0 +1,32 @@ +name: CIFuzz +on: + push: + paths: [ '**.c', '**.h', '**.m4', '**.sh', '**/Makefile.in', 'configure.ac', '.github/configs', '.github/workflows/cifuzz.yml' ] + pull_request: + paths: [ '**.c', '**.h', '**.m4', '**.sh', '**/Makefile.in', 'configure.ac', '.github/configs', '.github/workflows/cifuzz.yml' ] + +jobs: + Fuzzing: + if: github.repository != 'openssh/openssh-portable-selfhosted' + runs-on: ubuntu-latest + steps: + - name: Build Fuzzers + id: build + uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master + with: + oss-fuzz-project-name: 'openssh' + dry-run: false + language: c++ + - name: Run Fuzzers + uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master + with: + oss-fuzz-project-name: 'openssh' + fuzz-seconds: 600 + dry-run: false + language: c++ + - name: Upload Crash + uses: actions/upload-artifact@main + if: failure() && steps.build.outcome == 'success' + with: + name: artifacts + path: ./out/artifacts diff --git a/.github/workflows/selfhosted.yml b/.github/workflows/selfhosted.yml new file mode 100644 index 0000000..aa01c8b --- /dev/null +++ b/.github/workflows/selfhosted.yml @@ -0,0 +1,207 @@ +name: CI self-hosted + +on: + push: + paths: [ '**.c', '**.h', '**.m4', '**.sh', '**/Makefile.in', 'configure.ac', '.github/configs', '.github/run_tests.sh', '.github/workflows/selfhosted.yml' ] + +jobs: + selfhosted: + name: "${{ matrix.target }} ${{ matrix.config }}" + if: github.repository == 'openssh/openssh-portable-selfhosted' + runs-on: ${{ matrix.host }} + timeout-minutes: 600 + env: + HOST: ${{ matrix.host }} + TARGET_HOST: ${{ matrix.target }} + TARGET_CONFIG: ${{ matrix.config }} + TARGET_DOMAIN: ${{ startsWith(matrix.host, 'libvirt') && format('{0}-{1}-{2}', matrix.target, matrix.config, github.run_id) || matrix.target }} + EPHEMERAL: ${{ startsWith(matrix.host, 'libvirt') }} + PERSISTENT: ${{ startsWith(matrix.host, 'persist') }} + REMOTE: ${{ startsWith(matrix.host, 'remote') }} + VM: ${{ startsWith(matrix.host, 'libvirt') || startsWith(matrix.host, 'persist') }} + SSHFS: ${{ startsWith(matrix.host, 'libvirt') || startsWith(matrix.host, 'persist') || startsWith(matrix.host, 'remote') }} + BIGENDIAN: ${{ matrix.target == 'aix51' || matrix.target == 'nbsd-arm64be' || matrix.target == 'openwrt-mips' }} + strategy: + fail-fast: false + # We use a matrix in two parts: firstly all of the VMs are tested with the + # default config. "target" corresponds to a label associated with the + # worker. The default is an ephemeral VM running under libvirt. + matrix: + target: + - alpine + - centos7 + - debian-i386 + - dfly30 + - dfly48 + - dfly60 + - dfly62 + - dfly64 + - fbsd10 + - fbsd12 + - fbsd13 + - fbsd14 + - nbsd3 + - nbsd4 + - nbsd8 + - nbsd9 + - nbsd10 + - obsd51 + - obsd67 + - obsd72 + - obsd74 + - obsd76 + - obsd77 + - obsd78 + - obsdsnap + - obsdsnap-i386 + - omnios + - openindiana + - ubuntu-2204 + config: + - default + host: + - libvirt + include: + # Long-running/slow tests have access to high priority runners. + - { target: aix51, config: default, host: libvirt-hipri } + - { target: openindiana, config: pam, host: libvirt-hipri } + - { target: sol10, config: default, host: libvirt-hipri } + - { target: sol10, config: pam, host: libvirt-hipri } + - { target: sol11, config: default, host: libvirt-hipri } + - { target: sol11, config: pam-krb5, host: libvirt-hipri } + - { target: sol11, config: sol64, host: libvirt-hipri } + # Then we include extra libvirt test configs. + - { target: centos7, config: pam, host: libvirt } + - { target: debian-i386, config: pam, host: libvirt } + - { target: dfly30, config: without-openssl, host: libvirt} + - { target: dfly48, config: pam ,host: libvirt } + - { target: dfly58, config: pam, host: libvirt } + - { target: dfly60, config: pam, host: libvirt } + - { target: dfly62, config: pam, host: libvirt } + - { target: dfly64, config: pam, host: libvirt } + - { target: fbsd10, config: pam, host: libvirt } + - { target: fbsd12, config: pam, host: libvirt } + - { target: fbsd13, config: pam, host: libvirt } + - { target: fbsd14, config: pam, host: libvirt } + - { target: nbsd8, config: pam, host: libvirt } + - { target: nbsd9, config: pam, host: libvirt } + - { target: nbsd10, config: pam, host: libvirt } + - { target: omnios, config: pam, host: libvirt } + # ARM64 VMs + - { target: obsd-arm64, config: default, host: libvirt-arm64 } + # VMs with persistent disks that have their own runner. + - { target: win10, config: default, host: persist-win10 } + - { target: win10, config: cygwin-release, host: persist-win10 } + # Physical hosts with native runners. + - { target: ARM, config: default, host: ARM } + - { target: ARM64, config: default, host: ARM64 } + - { target: ARM64, config: pam, host: ARM64 } + # Physical hosts with remote runners. + - { target: debian-riscv64, config: default, host: remote-debian-riscv64 } + - { target: openwrt-mips, config: default, host: remote-openwrt-mips } + - { target: openwrt-mipsel, config: default, host: remote-openwrt-mipsel } + - { target: nbsd-arm64be, config: default, host: remote-nbsd-arm64be } + steps: + - name: shutdown VM if running + if: env.VM == 'true' + run: vmshutdown + - uses: actions/checkout@main + - name: autoreconf + run: autoreconf + - name: startup VM + if: env.VM == 'true' + run: vmstartup + working-directory: ${{ runner.temp }} + - name: copy and mount workspace + if: env.SSHFS == 'true' + run: sshfs_mount + working-directory: ${{ runner.temp }} + - name: configure + run: vmrun ./.github/configure.sh ${{ matrix.config }} +# - name: save config +# uses: actions/upload-artifact@main +# with: +# name: ${{ matrix.target }}-${{ matrix.config }}-config +# path: config.h + - name: make clean + run: vmrun make clean + - name: make + run: vmrun make + - name: make tests + run: vmrun ./.github/run_test.sh ${{ matrix.config }} + timeout-minutes: 600 + - name: show logs + if: failure() + run: vmrun 'for i in regress/failed*.log; do echo ====; echo logfile $i; echo =====; cat $i; done' + - name: save logs + if: failure() + uses: actions/upload-artifact@main + with: + name: ${{ matrix.target }}-${{ matrix.config }}-logs + path: | + config.h + config.log + regress/*.log + regress/log/* + regress/valgrind-out/ + - name: unmount workspace + if: always() && env.SSHFS == 'true' + run: fusermount -u ${GITHUB_WORKSPACE} || true + working-directory: ${{ runner.temp }} + + - name: bigendian interop - mount regress + if: env.SSHFS == 'true' && env.BIGENDIAN == 'true' + run: | + set -x + vmrun sudo chown -R $LOGNAME ~/$(basename ${GITHUB_WORKSPACE}) || true + vmrun "cd $(basename ${GITHUB_WORKSPACE}/regress) && sudo make clean" + sshfs_mount regress + vmrun "sudo mkdir -p $(dirname ${GITHUB_WORKSPACE})" + vmrun "sudo ln -s ~/$(basename ${GITHUB_WORKSPACE}) ${GITHUB_WORKSPACE}" + working-directory: ${{ runner.temp }} + + - name: bigendian interop - host build + if: env.SSHFS == 'true' && env.BIGENDIAN == 'true' + run: | + set -x + ./.github/configure.sh ${{ matrix.config }} + pwd + ls -ld regress || true + ls -l regress/check-perm || true + make clean + make + + - name: bigendian interop - test + if: env.SSHFS == 'true' && env.BIGENDIAN == 'true' + env: + TEST_SSH_UNSAFE_PERMISSIONS: 1 + run: | + set -x + echo "#!/bin/sh" >remote_sshd + echo "exec /usr/bin/ssh ${TARGET_DOMAIN} exec /home/builder/$(basename ${GITHUB_WORKSPACE})/sshd "'$@' >>remote_sshd + chmod 755 remote_sshd + make t-exec TEST_SSH_SSHD=`pwd`/remote_sshd LTESTS="try-ciphers kextype keytype" + + - name: bigendian interop - save logs + if: failure() && env.BIGENDIAN == 'true' + uses: actions/upload-artifact@main + with: + name: ${{ matrix.target }}-${{ matrix.config }}-interop-logs + path: | + config.h + config.log + regress/*.log + regress/log/* + + - name: bigendian interop - unmount regress + if: always() && env.SSHFS == 'true' && env.BIGENDIAN == 'true' + run: fusermount -z -u ${GITHUB_WORKSPACE}/regress || true + working-directory: ${{ runner.temp }} + + - name: lazily unmount workspace + if: always() && env.SSHFS == 'true' + run: fusermount -z -u ${GITHUB_WORKSPACE} || true + working-directory: ${{ runner.temp }} + - name: shutdown VM + if: always() && env.VM == 'true' + run: vmshutdown diff --git a/.github/workflows/upstream.yml b/.github/workflows/upstream.yml new file mode 100644 index 0000000..a190a49 --- /dev/null +++ b/.github/workflows/upstream.yml @@ -0,0 +1,81 @@ +name: OpenBSD + +on: + push: + branches: [ master ] + paths: [ '**.c', '**.h', '**.sh', '.github/workflows/upstream.yml' ] + +jobs: + selfhosted: + name: "upstream ${{ matrix.target }} ${{ matrix.config }}" + if: github.repository == 'openssh/openssh-portable-selfhosted' + runs-on: ${{ matrix.host }} + env: + EPHEMERAL: true + HOST: ${{ matrix.host }} + TARGET_HOST: ${{ matrix.target }} + TARGET_CONFIG: ${{ matrix.config }} + TARGET_DOMAIN: ${{ format('{0}-{1}-{2}', matrix.target, matrix.config, github.run_id) || matrix.target }} + strategy: + fail-fast: false + matrix: + host: + - libvirt + target: [ obsdsnap, obsdsnap-i386 ] + # TODO: restore 'ubsan' once fixed + config: [ default, kerberos5, without-openssl ] + include: + - { host: libvirt-arm64, target: obsdsnap-arm64, config: default } + - { host: libvirt-arm64, target: obsdsnap-arm64, config: kerberos5 } + - { host: libvirt-arm64, target: obsdsnap-arm64, config: without-openssl } + # - { host: libvirt-arm64, target: obsdsnap-arm64, config: ubsan } + steps: + - name: unmount stale workspace + run: fusermount -u ${GITHUB_WORKSPACE} || true + working-directory: ${{ runner.temp }} + - name: shutdown VM if running + run: vmshutdown + working-directory: ${{ runner.temp }} + - uses: actions/checkout@main + - name: startup VM + run: vmstartup + working-directory: ${{ runner.temp }} + - name: copy and mount workspace + run: sshfs_mount + working-directory: ${{ runner.temp }} + - name: update source + run: vmrun "cd /usr/src && if [ -d .git ]; then git pull && git log -n1; else cvs -q up -dPA usr.bin/ssh regress/usr.bin/ssh usr.bin/nc; fi" + - name: update netcat + run: vmrun "cd /usr/src/usr.bin/nc && make clean all && sudo make install" + - name: make clean + run: vmrun "cd /usr/src/usr.bin/ssh && make obj && make clean && cd /usr/src/regress/usr.bin/ssh && make obj && make clean && sudo chmod -R g-w /usr/src /usr/obj" + - name: make + run: vmrun "cd /usr/src/usr.bin/ssh && case ${{ matrix.config }} in without-openssl) make OPENSSL=no;; kerberos5) make KERBEROS5=yes;; ubsan) make DEBUG='-fsanitize-minimal-runtime -fsanitize=undefined';; *) make; esac" + - name: make install + run: vmrun "cd /usr/src/usr.bin/ssh && sudo make install && sudo /etc/rc.d/sshd -f restart" + - name: make tests` + run: vmrun "cd /usr/src/regress/usr.bin/ssh && case ${{ matrix.config }} in without-openssl) make OPENSSL=no;; ubsan) make DEBUG='-fsanitize-minimal-runtime -fsanitize=undefined';; *) make; esac" + env: + SUDO: sudo + timeout-minutes: 300 + - name: show logs + if: failure() + run: vmrun 'for i in /usr/src/regress/usr.bin/ssh/obj/*.log; do echo ====; echo logfile $i; echo =====; cat $i; done' + - name: save logs + if: failure() + uses: actions/upload-artifact@main + with: + name: ${{ matrix.target }}-${{ matrix.config }}-logs + path: | + /usr/src/regress/usr.bin/ssh/obj/*.log + /usr/src/regress/usr.bin/ssh/obj/log/* + - name: unmount workspace + if: always() + run: | + fusermount -u ${GITHUB_WORKSPACE} || true + fusermount -z -u ${GITHUB_WORKSPACE} || true + working-directory: ${{ runner.temp }} + - name: shutdown VM + if: always() + run: vmshutdown + working-directory: ${{ runner.temp }} diff --git a/.github/workflows/vm.yml b/.github/workflows/vm.yml new file mode 100644 index 0000000..dbfd6c1 --- /dev/null +++ b/.github/workflows/vm.yml @@ -0,0 +1,470 @@ +# For testing, you can set variables in your repo (Repo -> Settings -> +# Security -> Actions -> Variables) to restrict the tests that are run +# The supported variables are: +# +# RUN_ONLY_TARGET_CONFIG: Run only the single matching target and config, +# separated by spaces, eg "ubuntu-latest default". All other tests will +# fail immediately. +# +# LTESTS: Override the set of tests run. + +name: CI VM +on: + push: + paths: [ '**.c', '**.h', '**.m4', '**.sh', '**/Makefile.in', 'configure.ac', '.github/configs', '.github/workflows/vm.yml' ] + pull_request: + paths: [ '**.c', '**.h', '**.m4', '**.sh', '**/Makefile.in', 'configure.ac', '.github/configs', '.github/workflows/vm.yml' ] + +jobs: + dragonflybsd: + name: "dragonflybsd-${{ matrix.target }}" + if: github.repository != 'openssh/openssh-portable-selfhosted' + strategy: + fail-fast: false + matrix: + target: + - "6.4.2" + config: [default] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@main + - name: autoreconf + run: sh -c autoreconf + + - name: start DragonFlyBSD ${{ matrix.target }} VM + uses: vmactions/dragonflybsd-vm@v1 + with: + release: ${{ matrix.target }} + usesh: true + prepare: | + pkg install -y sudo + pw useradd builder -m + echo "builder ALL=(ALL:ALL) NOPASSWD: ALL" >>/usr/local/etc/sudoers + mkdir -p /var/empty /usr/local/etc + cp $GITHUB_WORKSPACE/moduli /usr/local/etc/moduli + + - name: set file perms + shell: dragonflybsd {0} + run: cd $GITHUB_WORKSPACE && chown -R builder . + - name: configure + shell: dragonflybsd {0} + run: cd $GITHUB_WORKSPACE && sudo -u builder ./configure --with-ssl-dir=/usr/local + - name: make clean + shell: dragonflybsd {0} + run: cd $GITHUB_WORKSPACE && sudo -u builder make clean + - name: make + shell: dragonflybsd {0} + run: cd $GITHUB_WORKSPACE && sudo -u builder make -j4 + - name: make tests + shell: dragonflybsd {0} + run: | + cd $GITHUB_WORKSPACE + sudo -u builder env SUDO=sudo make tests + + - name: "PAM: configure" + shell: dragonflybsd {0} + run: cd $GITHUB_WORKSPACE && sudo -u builder ./configure --with-ssl-dir=/usr/local --with-pam + - name: "PAM: make clean" + shell: dragonflybsd {0} + run: cd $GITHUB_WORKSPACE && sudo -u builder make clean + - name: "PAM: make" + shell: dragonflybsd {0} + run: cd $GITHUB_WORKSPACE && sudo -u builder make -j4 + - name: "PAM: make tests" + shell: dragonflybsd {0} + run: | + cd $GITHUB_WORKSPACE + sudo -u builder env SUDO=sudo SSHD_CONFOPTS="UsePam yes" make tests + + freebsd: + name: "freebsd-${{ matrix.target }}" + if: github.repository != 'openssh/openssh-portable-selfhosted' + strategy: + fail-fast: false + matrix: + target: + - "13.5" + - "14.3" + # - "15.0" # "pkg" breaks with a libutil.so error... + config: [default] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@main + - name: autoreconf + run: sh -c autoreconf + + - name: start FreeBSD ${{ matrix.target }} VM + uses: vmactions/freebsd-vm@v1 + with: + release: ${{ matrix.target }} + usesh: true + prepare: | + pkg install -y sudo + pw useradd builder -m + echo "builder ALL=(ALL:ALL) NOPASSWD: ALL" >>/usr/local/etc/sudoers + mkdir -p /var/empty /usr/local/etc + cp $GITHUB_WORKSPACE/moduli /usr/local/etc/moduli + + - name: set file perms + shell: freebsd {0} + run: cd $GITHUB_WORKSPACE && chown -R builder . + - name: configure + shell: freebsd {0} + run: cd $GITHUB_WORKSPACE && sudo -u builder ./configure + - name: make clean + shell: freebsd {0} + run: cd $GITHUB_WORKSPACE && sudo -u builder make clean + - name: make + shell: freebsd {0} + run: cd $GITHUB_WORKSPACE && sudo -u builder make -j4 + - name: make tests + shell: freebsd {0} + run: | + cd $GITHUB_WORKSPACE + sudo -u builder env SUDO=sudo make tests + + - name: "PAM: configure" + shell: freebsd {0} + run: cd $GITHUB_WORKSPACE && sudo -u builder ./configure --with-pam --with-audit=bsm + - name: "PAM: make clean" + shell: freebsd {0} + run: cd $GITHUB_WORKSPACE && sudo -u builder make clean + - name: "PAM: make" + shell: freebsd {0} + run: cd $GITHUB_WORKSPACE && sudo -u builder make -j4 + - name: "PAM: make tests" + shell: freebsd {0} + run: | + cd $GITHUB_WORKSPACE + sudo -u builder env SUDO=sudo SSHD_CONFOPTS="UsePam yes" make tests + + + netbsd: + name: "netbsd-${{ matrix.target }}" + if: github.repository != 'openssh/openssh-portable-selfhosted' + strategy: + fail-fast: false + matrix: + target: + - "9.0" + - "9.4" + - "10.0" + - "10.1" + config: [default] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@main + - name: autoreconf + run: sh -c autoreconf + + - name: start NetBSD ${{ matrix.target }} VM + uses: vmactions/netbsd-vm@v1 + with: + release: ${{ matrix.target }} + usesh: true + prepare: | + /usr/sbin/pkg_add sudo + /usr/sbin/useradd -m builder + echo "builder ALL=(ALL:ALL) NOPASSWD: ALL" >>/usr/pkg/etc/sudoers + mkdir -p /var/empty /usr/local/etc + cp $GITHUB_WORKSPACE/moduli /usr/local/etc/moduli + + - name: set file perms + shell: netbsd {0} + run: cd $GITHUB_WORKSPACE && /sbin/chown -R builder . + - name: configure + shell: netbsd {0} + run: cd $GITHUB_WORKSPACE && sudo -u builder ./configure + - name: make clean + shell: netbsd {0} + run: cd $GITHUB_WORKSPACE && sudo -u builder make clean + - name: make + shell: netbsd {0} + run: cd $GITHUB_WORKSPACE && sudo -u builder make -j4 + - name: make tests + shell: netbsd {0} + run: | + cd $GITHUB_WORKSPACE + sudo -u builder env SUDO=sudo make tests + + - name: "PAM: configure" + shell: netbsd {0} + run: cd $GITHUB_WORKSPACE && sudo -u builder ./configure --with-pam + - name: "PAM: make clean" + shell: netbsd {0} + run: cd $GITHUB_WORKSPACE && sudo -u builder make clean + - name: "PAM: make" + shell: netbsd {0} + run: cd $GITHUB_WORKSPACE && sudo -u builder make -j4 + - name: "PAM: make tests" + shell: netbsd {0} + run: | + cd $GITHUB_WORKSPACE + sudo -u builder env SUDO=sudo SSHD_CONFOPTS="UsePam yes" make tests + + + omnios: + name: "omnios-${{ matrix.target }}" + if: github.repository != 'openssh/openssh-portable-selfhosted' + strategy: + fail-fast: false + matrix: + target: + - "r151054" + - "r151046" + config: [default] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@main + - name: autoreconf + run: sh -c autoreconf + + - name: start OmniOS ${{ matrix.target }} VM + uses: vmactions/omnios-vm@v1 + with: + release: ${{ matrix.target }} + usesh: true + prepare: | + set -x + pfexec pkg refresh + pfexec pkg install build-essential + useradd -m builder + sed -e "s/^root.*ALL$/root ALL=(ALL) NOPASSWD: ALL/" /etc/sudoers >>/tmp/sudoers + mv /tmp/sudoers /etc/sudoers + echo "builder ALL=(ALL) NOPASSWD: ALL" >>/etc/sudoers + mkdir -p /var/empty /usr/local/etc + cp $GITHUB_WORKSPACE/moduli /usr/local/etc/moduli + + - name: set file perms + shell: omnios {0} + run: cd $GITHUB_WORKSPACE && chown -R builder . + - name: configure + shell: omnios {0} + run: cd $GITHUB_WORKSPACE && sudo -u builder ./configure + - name: make clean + shell: omnios {0} + run: cd $GITHUB_WORKSPACE && sudo -u builder make clean + - name: make + shell: omnios {0} + run: cd $GITHUB_WORKSPACE && sudo -u builder make + - name: make tests + shell: omnios {0} + run: | + cd $GITHUB_WORKSPACE + sudo -u builder make tests + + + openbsd: + name: "openbsd-${{ matrix.target }}" + if: github.repository != 'openssh/openssh-portable-selfhosted' + strategy: + fail-fast: false + matrix: + target: + - "7.3" + - "7.5" + - "7.6" + - "7.7" + - "7.8" + config: [default] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@main + - name: autoreconf + run: sh -c autoreconf + + - name: start OpenBSD ${{ matrix.target }} VM + uses: vmactions/openbsd-vm@v1 + with: + release: ${{ matrix.target }} + usesh: true + prepare: | + useradd -m builder + echo "permit nopass keepenv root" >/etc/doas.conf + echo "permit nopass keepenv builder" >>/etc/doas.conf + ls -l /etc/doas.conf + chown root:wheel /etc/doas.conf + chmod 644 /etc/doas.conf + mkdir -p /var/empty /usr/local/etc + cp $GITHUB_WORKSPACE/moduli /usr/local/etc/moduli + + - name: set file perms + shell: openbsd {0} + run: cd $GITHUB_WORKSPACE && chown -R builder . + - name: configure + shell: openbsd {0} + run: cd $GITHUB_WORKSPACE && doas -u builder ./configure + - name: make clean + shell: openbsd {0} + run: cd $GITHUB_WORKSPACE && doas -u builder make clean + - name: make + shell: openbsd {0} + run: cd $GITHUB_WORKSPACE && doas -u builder make -j4 + - name: make tests + shell: openbsd {0} + run: | + cd $GITHUB_WORKSPACE + doas -u builder env SUDO=doas make tests + + + openbsd-current-upstream: + # This job is special, and tests OpenBSD -current, both the underlying + # plaform (the latest snapshot) and most recent upstream code (or at least + # the most recent code in the github mirror) instead of OpenSSH Portable. + name: "openbsd-current-upstream" + if: github.repository != 'openssh/openssh-portable-selfhosted' + strategy: + fail-fast: false + runs-on: ubuntu-latest + steps: + - name: start OpenBSD VM + uses: vmactions/openbsd-vm@v1 + with: + copyback: false + nat: | + "20022": "22" + usesh: true + prepare: | + useradd -g wobj -m builder + echo "permit nopass keepenv root" >/etc/doas.conf + echo "permit nopass keepenv builder" >>/etc/doas.conf + ls -l /etc/doas.conf + chown root:wheel /etc/doas.conf + chmod 644 /etc/doas.conf + touch /etc/ssh/ssh_known_hosts + pkg_add git + + - name: Fetch sysupgrade version + run: | + ver=$(curl -s https://cdn.openbsd.org/pub/OpenBSD/snapshots/amd64/BUILDINFO) + echo "SNAPSHOT_VERSION=${ver}" >> $GITHUB_ENV + - name: check for cached sysupgrade + id: cache-sysupgrade + uses: actions/cache@v4 + with: + key: openbsd-sysupgrade ${{ env.SNAPSHOT_VERSION }} + path: /tmp/_sysupgrade/ + - name: push sysupgrade from cache to VM + if: steps.cache-sysupgrade.outputs.cache-hit == 'true' + run: rsync -av /tmp/_sysupgrade/ openbsd:/home/_sysupgrade/ + - name: upgrade to latest snapshot + run: ssh -q openbsd sysupgrade -s -k || true + - name: wait for upgrade + run: | + SECONDS=0; sleep 10; while ! ssh -q -oConnectTimeout=1 openbsd true; do sleep 10; echo waited ${SECONDS}s; done + ssh -q openbsd uname -a + - name: retrieve sysupgrade from VM to cache + if: steps.cache-sysupgrade.outputs.cache-hit != 'true' + run: | + mkdir -p /tmp/_sysupgrade/ + rsync -av openbsd:/home/_sysupgrade/ /tmp/_sysupgrade/ + - name: save sysupgrade to cache + if: steps.cache-sysupgrade.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + key: openbsd-sysupgrade ${{ env.SNAPSHOT_VERSION }} + path: /tmp/_sysupgrade/ + + - name: checkout upstream source + shell: openbsd {0} + run: | + umask 022 + cd /usr + rm -rf src/* + git clone --no-checkout --depth=1 --filter=tree:0 https://github.com/openbsd/src.git + cd /usr/src + git sparse-checkout set --no-cone Makefile usr.bin/Makefile usr.bin/Makefile.inc usr.bin/ssh usr.bin/nc regress/usr.bin/ssh + git checkout + git log -n1 + chown -R builder /usr/src + chmod -R go-w /usr/src/ /usr/obj/ + - name: make ssh + shell: openbsd {0} + run: | + cd /usr/src/usr.bin/ssh && make -j4 || make + make install + /etc/rc.d/sshd restart + - name: make nc + shell: openbsd {0} + run: cd /usr/src/usr.bin/nc && make && make install + - name: make tests + shell: openbsd {0} + run: | + cd /usr/src/regress/usr.bin/ssh + make obj + doas -u builder env SUDO=doas TEST_SSH_UNSAFE_PERMISSIONS=yes TEST_SSH_FAIL_FATAL=yes TEST_SSH_HOSTBASED_AUTH=setupandrun make + - name: retrieve logs + if: failure() + run: | + rsync -a openbsd:/usr/obj/regress/usr.bin/ssh/ regress-logs/ + for i in regress-logs/failed*.log; do echo ===; echo LOGFILE: $i; echo ===; cat $i; echo; done + - name: save logs + if: failure() + uses: actions/upload-artifact@main + with: + name: openbsd-current-upstream-logs + path: regress-logs/*.log + + + solaris: + name: "solaris-${{ matrix.target }}" + if: github.repository != 'openssh/openssh-portable-selfhosted' + strategy: + fail-fast: false + matrix: + target: + - "11.4-gcc" + config: [default] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@main + - name: autoreconf + run: sh -c autoreconf + + - name: start Solaris ${{ matrix.target }} VM + uses: vmactions/solaris-vm@v1 + with: + release: ${{ matrix.target }} + usesh: true + prepare: | + set -x + useradd -m builder + sed -e "s/^root.*ALL$/root ALL=(ALL) NOPASSWD: ALL/" /etc/sudoers >>/tmp/sudoers + mv /tmp/sudoers /etc/sudoers + echo "builder ALL=(ALL) NOPASSWD: ALL" >>/etc/sudoers + mkdir -p /var/empty /usr/local/etc + cp $GITHUB_WORKSPACE/moduli /usr/local/etc/moduli + + - name: set file perms + shell: solaris {0} + run: cd $GITHUB_WORKSPACE && chown -R builder . + - name: configure + shell: solaris {0} + run: cd $GITHUB_WORKSPACE && sudo -u builder ./configure + - name: make clean + shell: solaris {0} + run: cd $GITHUB_WORKSPACE && sudo -u builder make clean + - name: make + shell: solaris {0} + run: cd $GITHUB_WORKSPACE && sudo -u builder make + - name: make tests + shell: solaris {0} + run: | + cd $GITHUB_WORKSPACE + sudo -u builder make tests + + - name: "PAM: configure" + shell: solaris {0} + run: cd $GITHUB_WORKSPACE && sudo -u builder ./configure --with-pam + - name: "PAM: make clean" + shell: solaris {0} + run: cd $GITHUB_WORKSPACE && sudo -u builder make clean + - name: "PAM: make" + shell: solaris {0} + run: cd $GITHUB_WORKSPACE && sudo -u builder make + - name: "PAM: make tests" + shell: solaris {0} + run: | + cd $GITHUB_WORKSPACE + sudo -u builder make tests + diff --git a/.gitignore b/.gitignore index 41d505c..9075330 100644 --- a/.gitignore +++ b/.gitignore @@ -1,20 +1,22 @@ +*~ Makefile buildpkg.sh config.h -config.h.in~ config.log config.status openbsd-compat/Makefile openbsd-compat/regress/Makefile +openbsd-compat/include openssh.xml opensshd.init survey.sh **/*.o **/*.lo **/*.so +**/*.dylib +**/*.dll **/*.out **/*.a -**/*.un~ **/.*.swp autom4te.cache/ scp @@ -29,7 +31,9 @@ ssh-keysign ssh-pkcs11-helper ssh-sk-helper sshd -!regress/misc/fuzz-harness/Makefile -!regress/unittests/sshsig/Makefile +sshd-session +sshd-auth +!regress/misc/**/Makefile +!regress/unittests/**/Makefile tags diff --git a/.skipped-commit-ids b/.skipped-commit-ids index ec7831e..f4b7ee2 100644 --- a/.skipped-commit-ids +++ b/.skipped-commit-ids @@ -1,3 +1,5 @@ +747219d54565030ff7c45298b9f5e971801f6cb2 moduli-gen Makefile tweak +c2eb57285424f819f9520fa33e0d6d3c4a361a5e moduli-gen.sh tweak 509bb19bb9762a4b3b589af98bac2e730541b6d4 clean sshd random relinking kit 5317f294d63a876bfc861e19773b1575f96f027d remove libssh from makefiles a337e886a49f96701ccbc4832bed086a68abfa85 Makefile changes @@ -37,6 +39,14 @@ ef9341d5a50f0d33e3a6fbe995e92964bc7ef2d3 Makefile relinking changes fb39324748824cb0387e9d67c41d1bef945c54ea Makefile change 5f378c38ad8976d507786dc4db9283a879ec8cd0 Makefile change 112aacedd3b61cc5c34b1fa6d9fb759214179172 Makefile change +a959fc45ea3431b36f52eda04faefc58bcde00db groupaccess.c changes +6d07e4606997e36b860621a14dd41975f2902f8f Makefile.inc +c7246a6b519ac390ca550719f91acfdaef1fa0f0 Makefile relink change +ef7ecdb6dd2542f42fa7236d17ac0b144851f0b5 ssh-keygen, fixup'ed into 21682417 +da414a364c25b187fc686da7aacec2c35d29238a ssh-keygen, fixup'ed into 21682417 +a05e13a7e2c0b65bb4b47184fef731243431c6ff Makefile.inc +7e8178786157e863f6ff63c5d55200d7b6b04f9e remove old sandbox files +98eefed432ff8253b307002e20d28da14b93e7e3 Makefile.inc Old upstream tree: diff --git a/ChangeLog b/ChangeLog index 2ef1164..65e75a5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6764 +1,10627 @@ -commit 6ebc4dd77a479892d5ca0cd2a567a651f70aad82 +commit 4168c905943f7f715182180b9f7c8cda54af2514 Author: Damien Miller -Date: Tue Feb 18 19:03:42 2025 +1100 +Date: Thu Apr 2 18:56:48 2026 +1100 - openssh-9.9p2 + depend + +commit f8b9d694fc20349b6c48a4af03a0499dea00f5f9 +Author: Damien Miller +Date: Thu Apr 2 18:55:50 2026 +1100 + + Update versions in RPM spec files -commit 38df39ecf278a7ab5794fb03c01286f2cfe82c0d +commit 5aa09926fbf050d484a79717fadec8360c5c5645 Author: djm@openbsd.org -Date: Tue Feb 18 08:02:48 2025 +0000 +Date: Thu Apr 2 07:52:15 2026 +0000 - upstream: Fix cases where error codes were not correctly set + upstream: adapt to username validity check change - Reported by the Qualys Security Advisory team. ok markus@ - - OpenBSD-Commit-ID: 7bcd4ffe0fa1e27ff98d451fb9c22f5fae6e610d + OpenBSD-Regress-ID: d22c66ca60f0d934a75e6ca752c4c11b9f4a5324 -commit 5e07dee272c34e193362fba8eda0e3c453f3c773 +commit eb3a5bb2abd4798ff546564eb2210d188efaf0f1 Author: djm@openbsd.org -Date: Tue Feb 18 08:02:12 2025 +0000 +Date: Thu Apr 2 07:51:12 2026 +0000 - upstream: Don't reply to PING in preauth phase or during KEX - - Reported by the Qualys Security Advisory team. ok markus@ + upstream: openssh-10.3 - OpenBSD-Commit-ID: c656ac4abd1504389d1733d85152044b15830217 + OpenBSD-Commit-ID: 05e22de74e090e5a174998fa5799317d70ad19c4 -commit fb071011fb843142282b8b8a69cbb15e9b0b9485 +commit 76685c9b09a66435cd2ad8373246adf1c53976d3 Author: djm@openbsd.org -Date: Mon Feb 10 23:00:29 2025 +0000 +Date: Thu Apr 2 07:50:55 2026 +0000 - upstream: fix "Match invalid-user" from incorrectly being activated + upstream: move username validity check for usernames specified on - in initial configuration pass when no other predicates were present on the - match line + the commandline to earlier in main(), specifically before some contexts where + a username with shell characters might be expanded by a %u directive in + ssh_config. + MIME-Version: 1.0 + Content-Type: text/plain; charset=UTF-8 + Content-Transfer-Encoding: 8bit - OpenBSD-Commit-ID: 02703b4bd207fafd03788bc4e7774bf80be6c9a8 - -commit 729a26a978dd39db60d4625bdfb5405baa629e59 -Author: Damien Miller -Date: Wed Oct 30 14:25:14 2024 +1100 - - fix uint64_t types; reported by Tom G. Christensen - -commit 33c5f384ae03a5d1a0bd46ca0fac3c62e4eaf784 -Author: Damien Miller -Date: Sun Oct 27 13:28:11 2024 +1100 - - htole64() etc for systems without endian.h + We continue to recommend against using untrusted input on + the SSH commandline. Mitigations like this are not 100% + guarantees of safety because we can't control every + combination of user shell and configuration where they are + used. + + Reported by Florian Kohnhäuser + + OpenBSD-Commit-ID: 25ef72223f5ccf1c38d307ae77c23c03f59acc55 -commit fe8d28a7ebbaa35cfc04a21263627f05c237e460 +commit fd1c7e131f331942d20f42f31e79912d570081fa Author: djm@openbsd.org -Date: Sun Oct 27 02:06:59 2024 +0000 +Date: Thu Apr 2 07:48:13 2026 +0000 - upstream: explicitly include endian.h + upstream: correctly match ECDSA signature algorithms against - OpenBSD-Commit-ID: 13511fdef7535bdbc35b644c90090013da43a318 + algorithm allowlists: HostKeyAlgorithms, PubkeyAcceptedAlgorithms and + HostbasedAcceptedAlgorithms. + + Previously, if any ECDSA type (say "ecdsa-sha2-nistp521") was + present in one of these lists, then all ECDSA algorithms would + be permitted. + + Reported by Christos Papakonstantinou of Cantina and Spearbit. + + OpenBSD-Commit-ID: c790e2687c35989ae34a00e709be935c55b16a86 -commit 11f348196b3fb51c3d8d1f4f36db9d73f03149ed +commit 487e8ac146f7d6616f65c125d5edb210519b833a Author: djm@openbsd.org -Date: Sun Oct 27 02:06:01 2024 +0000 +Date: Thu Apr 2 07:42:16 2026 +0000 - upstream: fix ML-KEM768x25519 KEX on big-endian systems; spotted by + upstream: when downloading files as root in legacy (-O) mode and - jsg@ feedback/ok deraadt@ + without the -p (preserve modes) flag set, clear setuid/setgid bits from + downloaded files as one might expect. - OpenBSD-Commit-ID: 26d81a430811672bc762687166986cad40d28cc0 + AFAIK this bug dates back to the original Berkeley rcp program. + + Reported by Christos Papakonstantinou of Cantina and Spearbit. + + OpenBSD-Commit-ID: 49e902fca8dd933a92a9b547ab31f63e86729fa1 -commit 19bcb2d90c6caf14abf386b644fb24eb7afab889 +commit c805b97b67c774e0bf922ffb29dfbcda9d7b5add Author: djm@openbsd.org -Date: Thu Sep 26 23:55:08 2024 +0000 +Date: Thu Apr 2 07:39:57 2026 +0000 - upstream: fix previous change to ssh_config Match, which broken on + upstream: add missing askpass check when using - negated Matches; spotted by phessler@ ok deraadt@ + ControlMaster=ask/autoask and "ssh -O proxy ..."; reported by Michalis + Vasileiadis - OpenBSD-Commit-ID: b1c6acec66cd5bd1252feff1d02ad7129ced37c7 + OpenBSD-Commit-ID: 8dd7b9b96534e9a8726916b96d36bed466d3836a -commit 66878e12a207fa9746dee3e2bdcca29b704cf035 +commit 78d549857e0cc480c3cbb0a3571078920e3b79c5 Author: djm@openbsd.org -Date: Wed Sep 25 01:24:04 2024 +0000 +Date: Thu Apr 2 07:38:14 2026 +0000 - upstream: fix regression introduced when I switched the "Match" - - criteria tokeniser to a more shell-like one. Apparently the old tokeniser - (accidentally?) allowed "Match criteria=argument" as well as the "Match - criteria argument" syntax that we tested for. + upstream: Fix possible sshd crash when sshd_config set MaxStartups - People were using this syntax so this adds back support for - "Match criteria=argument" + to a value <10 using the single-argument form of MaxStartups (e.g. + MaxStartups=3). This doesn't affect the three-argument form of the directive + (e.g. MaxStartups 3:20:5). - bz3739 ok dtucker + Patch from Peter Kaestle via bz3941 - OpenBSD-Commit-ID: d1eebedb8c902002b75b75debfe1eeea1801f58a + OpenBSD-Commit-ID: 1ad093cae69f55ebfdea1ab24318aefd593d63b8 -commit ff2cd1dd5711ff88efdf26662d6189d980439a1f +commit 5d72f1865b95ebfd99ea7baa8f6f2a4b721d151e Author: Damien Miller -Date: Wed Sep 25 11:15:45 2024 +1000 +Date: Thu Apr 2 18:32:00 2026 +1100 - gss-serv.c needs sys/param.h + properly bail out when PAM changes username - From Void Linux - -commit 2c12ae8cf9b0b7549ae097c4123abeda0ee63e5b -Author: Damien Miller -Date: Wed Sep 25 11:13:05 2024 +1000 - - build construct_utmp() when USE_BTMP is set + OpenSSH doesn't support PAM changing its conception of the + username via a module calling pam_set_item(h, PAM_USER, ...). + We were supposed to bail out here, but I messed up while "fixing" + this last time and dropped a return statement. - Fixes compile error on Void Linux/Musl + Reported by Mike Damm -commit c7fda601186ff28128cfe3eab9c9c0622de096e1 -Author: Christoph Ostarek -Date: Wed Jul 3 12:46:59 2024 +0200 +commit fe86c39751d38eb9e9b03ace1e31aa4586ea6660 +Author: Michael Forney +Date: Wed Apr 1 12:09:00 2026 +1100 - fix utmpx ifdef + avoid k suffix in dd count operand in sftp-resume test - 02e16ad95fb1f56ab004b01a10aab89f7103c55d did a copy-paste for - utmpx, but forgot to change the ifdef appropriately + Not all dd implementations support this. POSIX only specifies + suffixes for block size operands. + + Instead, just use 1024k to avoid the special case. This also removes + an incorrect redirection operator that appeared in the 1m case. -commit 7cf4dc414de689c467e58e49fb83f6609c3ed36b -Author: Darren Tucker -Date: Mon Sep 23 20:54:26 2024 +1000 +commit 52c01f2a8019002c70cfd93be87ff9adee1d0e73 +Author: Michael Forney +Date: Tue Mar 31 12:54:22 2026 +1100 - Remove non-9.9 branch statuses. + add missing include to unit tests for printf + + This fixes the build with --without-openssl on musl. glibc worked + previously because it got stdio.h implicitly through resolv.h. -commit 8513f4d30ae85d17b3b08da6bc3be76f8c73123c +commit 1340d3fa8e4bb122906a82159c4c9b91584d65ce Author: Darren Tucker -Date: Mon Sep 23 20:52:31 2024 +1000 +Date: Mon Mar 30 21:58:44 2026 +1100 - Add 9.9 branch to CI status console. - -commit 53a80baaebda180f46e6e8571f3ff800e1f5c496 -Author: Damien Miller -Date: Fri Sep 20 08:20:48 2024 +1000 - - autogenerated files for release + Add proxyjump.sh omitted from previous commit. -commit 46d1fb16b20e971b9ac15e86a3d3e350b49c9ad6 -Author: Damien Miller -Date: Fri Sep 20 08:20:13 2024 +1000 +commit 607bd871ec029e9aa22e632a22547250f3cae223 +Author: djm@openbsd.org +Date: Mon Mar 30 07:19:02 2026 +0000 - update version numbers + upstream: add a regression test for ProxyJump/-J; ok dtucker + + OpenBSD-Regress-ID: 400dc1b5fb7f2437d0dfbd2eb9a3583dafb412b3 -commit 0bdca1f218971b38728a0a129f482476baff0968 -Author: djm@openbsd.org -Date: Thu Sep 19 22:17:44 2024 +0000 +commit 55fc7bfd1d3a46f4856fd68f09da60d901fac626 +Author: dtucker@openbsd.org +Date: Tue Mar 24 12:31:35 2026 +0000 - upstream: openssh-9.9 + upstream: Use ~/.shosts for Hostbased test. - OpenBSD-Commit-ID: 303417285f1a73b9cb7a2ae78d3f493bbbe31f98 + OpenBSD-Regress-ID: ab64fd0a86422df1eadacde56c0a2cff5d93425d -commit ef2d7f2d3e1b4c9ae71bacf963e76a92ab8be543 -Author: Damien Miller -Date: Wed Sep 18 16:03:23 2024 +1000 +commit 445db5cb620d73c9af1f1791c523aaf3d2236854 +Author: dtucker@openbsd.org +Date: Tue Mar 24 10:21:14 2026 +0000 - include openbsd-compat/base64.c license in LICENSE + upstream: Ensure known_hosts file exists when setting up. + + OpenBSD-Regress-ID: 92721cad4c219fe62b7b795a73505c22e56f09e0 -commit 7ef362b989c8d1f7596f557f22e5924b9c08f0ea -Author: Damien Miller -Date: Wed Sep 18 09:01:23 2024 +1000 +commit 2ecfcc0aae651621535e345a1c23ff6d2a9593c9 +Author: dtucker@openbsd.org +Date: Mon Mar 23 09:53:52 2026 +0000 - conditionally include mman.h in arc4random code + upstream: Check if host keys exist before adding them, and expand + + on the warning about modifying the system config. + + OpenBSD-Regress-ID: 68038da909f9c992375b7665dab0331d6af426b7 -commit 5fb2b5ad0e748732a27fd8cc16a7ca3c21770806 -Author: Damien Miller -Date: Tue Sep 17 11:53:24 2024 +1000 +commit 5576e260a0f9836ca55c8279e342c63d1a0851d1 +Author: dtucker@openbsd.org +Date: Mon Mar 23 09:09:36 2026 +0000 - fix bug in recently-added sntrup761 fuzzer + upstream: Add special handling of - key values need to be static to persist across invocations; - spotted by the Qualys Security Advisory team. + TEST_SSH_HOSTBASED_AUTH=setupandrun. + + This will MODIFY THE CONFIG OF THE SYSTEM IT IS RUNNING ON to enable + hostbased authentication to/from itself and run the hostbased tests. It + won't undo these changes, so don't do this on a system where this matters. + + OpenBSD-Regress-ID: ae5a86db1791a2b8f999b07b5c8cc756d40bf645 -commit 0ca128c9ee894f1b0067abd473bfb33171df67f8 +commit 0a0ef4515361143cad21afa072319823854c1cf6 Author: djm@openbsd.org -Date: Mon Sep 16 05:37:05 2024 +0000 +Date: Mon Mar 30 07:18:24 2026 +0000 - upstream: use 64 bit math to avoid signed underflow. upstream code + upstream: apply the same validity rules to usernames and hostnames - relies on using -fwrapv to provide defined over/underflow behaviour, but we - use -ftrapv to catch integer errors and abort the program. ok dtucker@ + set for ProxyJump/-J on the commandline as we do for destination user/host + names. - OpenBSD-Commit-ID: 8933369b33c17b5f02479503d0a92d87bc3a574b + Specifically, they are no longer allowed to contain most characters + that have special meaning for common shells. Special characters are + still allowed in ProxyJump commands that are specified in the config + files. + + This _reduces_ the chance that shell characters from a hostile -J + option from ending up in a shell execution context. + + Don't pass untrusted stuff to the ssh commandline, it's not intended + to be a security boundary. We try to make it safe where we can, but + we can't make guarantees, because we can't know the parsing rules + and special characters for all the shells in the world, nor can we + know what the user does with this data in their ssh_config wrt + percent expansion, LocalCommand, match exec, etc. + + While I'm in there, make ProxyJump and ProxyCommand first-match-wins + between each other. + + reported by rabbit; ok dtucker@ + + OpenBSD-Commit-ID: f05ad8a1eb5f6735f9a935a71a90580226759263 -commit f82e5e22cad88c81d8a117de74241328c7b101c3 -Author: jmc@openbsd.org -Date: Sun Sep 15 08:27:38 2024 +0000 +commit b62a6cfbed3481dac8bff35fab22cf489bb0b77f +Author: djm@openbsd.org +Date: Sun Mar 29 01:08:13 2026 +0000 - upstream: minor grammar/sort fixes for refuseconnection; ok djm + upstream: switch from int to long long for bandwidth calculations; - OpenBSD-Commit-ID: 1c81f37b138b8b66abba811fec836388a0f3e6da + fixes rate display when rate > 2GB/s; based on patch from Cyril Servant + feedback/ok deraadt@ + + OpenBSD-Commit-ID: 071eb48c4cba598d70ea3854bef7c49ddfabf8d3 -commit 0c1165fc78e8fe69b5df71f81a8f944554a68b53 +commit 54443b8665c9c29ea0e3f5a5176d8f3c3403ad7c Author: Damien Miller -Date: Sun Sep 15 13:30:13 2024 +1000 +Date: Sun Mar 29 16:43:59 2026 +1100 - avoid gcc warning in fuzz test + depend -commit ce171d0718104b643854b53443ff72f7283d33f2 -Author: djm@openbsd.org -Date: Sun Sep 15 03:09:44 2024 +0000 +commit c90f46b6230826cdadacd6c32b62b0f8106a09da +Author: Damien Miller +Date: Sun Mar 29 16:42:33 2026 +1100 - upstream: bad whitespace in config dump output + use nonnull attribute when available - OpenBSD-Commit-ID: d899c13b0e8061d209298eaf58fe53e3643e967c + Set this attribute on a few string to avoid compiler warnings from + -Wunterminated-string-initialization warnings in recent gcc. -commit 671c440786a5a66216922f15d0007b60f1e6733f +commit bdaf65ae51d62c6cb676bd341cc34217c1b24920 Author: Damien Miller -Date: Sun Sep 15 12:53:59 2024 +1000 +Date: Sun Mar 29 16:24:59 2026 +1100 - use construct_utmp to construct btmp records + fix state confusion between PAM and privsep code - Simpler and removes some code with the old-style BSD license. + Commits b9a6dd4d6 and df2b28163 introduced a potential desynchronisation + between the PAM code and the sshd-session monitor that could result in + authentication bypass if the unprivileged sshd-auth process had been + compromised. + + Reported by Ben Edelman of NIST. Only git HEAD is affected, these + changes have not yet been included in an OpenSSH release. -commit 930cb02b6113df72fbc732b9feb8e4f490952a81 -Author: djm@openbsd.org -Date: Sun Sep 15 02:20:51 2024 +0000 +commit 6eb5a68c42a587df802d3d9a19088671269ffca8 +Author: Laurent Chardon +Date: Sat Mar 28 04:22:54 2026 -0400 - upstream: update the Streamlined NTRU Prime code from the "ref" + openbsd-compat: reword EAI_NONAME error string - implementation in SUPERCOP 20201130 to the "compact" implementation in - SUPERCOP 20240808. The new version is substantially faster. Thanks to Daniel - J Bernstein for pointing out the new implementation (and of course for - writing it). + Reword the EAI_NONAME message in fake-rfc2553.c to make it + clearer and grammatically correct. - tested in snaps/ok deraadt@ + While there, remove a couple of stray periods from other error + strings to keep the messages consistent. - OpenBSD-Commit-ID: bf1a77924c125ecdbf03e2f3df8ad13bd3dafdcb + No functional change. -commit 9306d6017e0ce5dea6824c29ca5ba5673c2923ad -Author: djm@openbsd.org -Date: Sun Sep 15 01:19:56 2024 +0000 +commit fd7d4b2b52deaf296b06d78b85c97fdae31912e8 +Author: Icenowy Zheng +Date: Sun Mar 22 15:13:31 2026 +0800 - upstream: document Match invalid-user + seccomp sandbox: allow riscv_hwprobe syscall if present - OpenBSD-Commit-ID: 2c84a9b517283e9711e2812c1f268081dcb02081 + The development branch of zlib-ng now contains code for utilizing + riscv_hwprobe syscall to retrieve availability information for several + RISC-V extensions (and accelerate deflate algorithm with them). + + As the seccomp sandbox of OpenSSH will raise SIGSYS for filtered out + syscalls, this will abruptly terminate the process when the + riscv_hwprobe syscall is tried. + + Put it into the allowlist to prevent process termination. As all + syscalls here are guarded by #ifdef's, the same will be done for + riscv_hwprobe, and thus on non-RISC-V builds nothing will happen. + + Signed-off-by: Icenowy Zheng -commit 0118a4da21147a88a56dc8b90bbc2849fefd5c1e +commit fd5018fbeb6e91ae4321490c2825ecc632b83748 Author: djm@openbsd.org -Date: Sun Sep 15 01:18:26 2024 +0000 +Date: Sat Mar 28 05:16:18 2026 +0000 - upstream: add a "Match invalid-user" predicate to sshd_config Match + upstream: ensure c->local_window doesn't underflow during updates; - options. - - This allows writing Match conditions that trigger for invalid username. - E.g. + similar to checks performed elsewhere. From Renaud Allard - PerSourcePenalties refuseconnection:90s - Match invalid-user - RefuseConnection yes + OpenBSD-Commit-ID: 4827c10807936e9ab9af2cf1c7379e1f56dbdeac + +commit 8331cb9daafd23391de4379e9977ff159bb8242e +Author: djm@openbsd.org +Date: Sat Mar 28 05:10:25 2026 +0000 + + upstream: fix base16 parsing; currently unused. From Renaud Allard - Will effectively penalise bots try to guess passwords for bogus accounts, - at the cost of implicitly revealing which accounts are invalid. + OpenBSD-Commit-ID: 3f6e5d4c6a2550d5a7e3c33bcd895b7f8e42196b + +commit 21ecb5fd72ee442a8b1eb5011c7f929ba8ce02f9 +Author: djm@openbsd.org +Date: Sat Mar 28 05:07:12 2026 +0000 + + upstream: mention that RevokedKeys is read by the server at each - feedback markus@ + authentication time and should only ever be replaced atomically. - OpenBSD-Commit-ID: 93d3a46ca04bbd9d84a94d1e1d9d3a21073fbb07 + OpenBSD-Commit-ID: eeedf5a10331ac4e39fbd2fc41e4a11c38b2ef9b -commit 7875975136f275619427604900cb0ffd7020e845 +commit c5182e3f06f9f1fd86d62b9dcd0397408dd698da Author: djm@openbsd.org -Date: Sun Sep 15 01:11:26 2024 +0000 +Date: Sat Mar 28 05:06:16 2026 +0000 - upstream: Add a "refuseconnection" penalty class to sshd_config + upstream: fix potential hang if /etc/moduli doesn't contain the - PerSourcePenalties - - This allows penalising connection sources that have had connections - dropped by the RefuseConnection option. ok markus@ + requested DH group values; from 77c9ca, ok dtucker@, markus@ - OpenBSD-Commit-ID: 3c8443c427470bb3eac1880aa075cb4864463cb6 + OpenBSD-Commit-ID: 1bf402cdb8876237c280ac77fbf7fafd2c16c5ae -commit 8d21713b669b8516ca6d43424a356fccc37212bb +commit d3efbba14fda78ed7b15fbc34cf34c1cf27d1716 +Author: Darren Tucker +Date: Thu Mar 19 17:57:26 2026 +1100 + + Add a VM-based test for OpenBSD-current. + +commit 4bb4f1601e0776e71cfca50aae3680eb0771e2d0 +Author: Darren Tucker +Date: Mon Mar 23 17:50:40 2026 +1100 + + Add a Valgrind test of the PAM config. + +commit 12da685dfc98b14dddb5977a1fc52d06474f3308 +Author: Darren Tucker +Date: Thu Mar 19 17:52:54 2026 +1100 + + Upstream tests don't use the config file. + +commit 2ca6eef69d7dbecfd67cede25ea6a9aa1074ba3e Author: djm@openbsd.org -Date: Sun Sep 15 01:09:40 2024 +0000 +Date: Mon Mar 23 01:33:46 2026 +0000 - upstream: Add a sshd_config "RefuseConnection" option + upstream: clarify that Authorized(Keys|Principals)(File|Command) - If set, this will terminate the connection at the first authentication - request (this is the earliest we can evaluate sshd_config Match blocks) + are only consulted for valid users. - ok markus@ + clarify that TOKENS are expanded without sanitisation or escaping + and that it's the user's reponsibility to ensure their usage is + safe. - OpenBSD-Commit-ID: 43cc2533984074c44d0d2f92eb93f661e7a0b09c + prompted by bz3936; feedback/ok deraadt@ + + OpenBSD-Commit-ID: cd58abad1137346ba2dee55fa9ebb975f5fa7a06 -commit acad117e66018fe1fa5caf41b36e6dfbd61f76a1 +commit 443616ce9070d370c97271347e91fcfd24b5df84 Author: djm@openbsd.org -Date: Sun Sep 15 00:58:01 2024 +0000 +Date: Thu Mar 19 02:36:28 2026 +0000 - upstream: switch sshd_config Match processing to the argv tokeniser + upstream: repair ssh-keysign after pledge changes; spotted/tested - too; ok markus@ + by naddy@ ok deraadt@ - OpenBSD-Commit-ID: b74b5b0385f2e0379670e2b869318a65b0bc3923 + OpenBSD-Commit-ID: fccc6c7994c8f45c4417efe490d23154d9caaa6d -commit baec3f7f4c60cd5aa1bb9adbeb6dfa4a172502a8 -Author: djm@openbsd.org -Date: Sun Sep 15 00:57:36 2024 +0000 +commit 552a5c786b60a9cfe0d2c157dd18f78950529513 +Author: dtucker@openbsd.org +Date: Wed Mar 11 09:10:59 2026 +0000 - upstream: switch "Match" directive processing over to the argv + upstream: Check return values of fcntl(... O_CLOEXEC) - string tokeniser, making it possible to use shell-like quoting in Match - directives, particularly "Match exec". ok markus@ + calls by reusing the macro in monitor.c. Flagged by Coverity CID + 901297 in ssh-sk-client.c, a few other instances added for good measure. + begrudging ok deraadt@ - OpenBSD-Commit-ID: 0877309650b76f624b2194c35dbacaf065e769a5 + OpenBSD-Commit-ID: b9de92e17ac0b04348770e5a25cb15a02b416926 -commit dd424d7c382c2074ab70f1b8ad4f169a10f60ee7 -Author: djm@openbsd.org -Date: Sun Sep 15 00:47:01 2024 +0000 +commit 24168275e6d0b29cf2233c3f2c1d4a4614feb582 +Author: dtucker@openbsd.org +Date: Wed Mar 11 09:04:17 2026 +0000 - upstream: include pathname in some of the ssh-keygen passphrase + upstream: Fix potential 1-byte array overrun - prompts. Helps the user know what's going on when ssh-keygen is invoked via - other tools. Requested in GHPR503 + in the case where read() returns exactly 100 bytes. Flagged by Coverity + CID 901296, ok djm@ - OpenBSD-Commit-ID: 613b0bb6cf845b7e787d69a5b314057ceda6a8b6 + OpenBSD-Commit-ID: 66a96b08166e63dcbeed00297c33f09c4f22c1f7 -commit 62bbf8f825cc390ecb0523752ddac1435006f206 +commit 70a41262839a2d65ca8ef9e8ea34ad471c52afa1 Author: djm@openbsd.org -Date: Sun Sep 15 00:41:18 2024 +0000 +Date: Tue Mar 10 07:27:14 2026 +0000 - upstream: Do not apply authorized_keys options when signature + upstream: whitespace - verification fails. Prevents restrictive key options being incorrectly - applied to subsequent keys in authorized_keys. bz3733, ok markus@ + OpenBSD-Commit-ID: b16d2b4a96406538fa181053926cba44abca7f29 + +commit ef98b6014bc3268e904092894ffcb63022172a97 +Author: deraadt@openbsd.org +Date: Tue Mar 10 06:35:29 2026 +0000 + + upstream: when unveils error our, use correct variable - OpenBSD-Commit-ID: ba3776d9da4642443c19dbc015a1333622eb5a4e + OpenBSD-Commit-ID: 6b496c10965e70413a9916a8823839c553c6b2c4 -commit 49f325fd47af4e53fcd7aafdbcc280e53f5aa5ce -Author: Wu Weixin -Date: Fri Aug 2 22:16:40 2024 +0800 +commit beba5884dfe8cc30aadef439af5e5d784b5788b1 +Author: deraadt@openbsd.org +Date: Tue Mar 10 03:45:01 2026 +0000 - Fix without_openssl always being set to 1 + upstream: When execve() failure is indicated on the pipe, replicate - In Fedora systems, %{?rhel} is empty. In RHEL systems, %{?fedora} is - empty. Therefore, the original code always sets without_openssl to 1. + the same error conditions as the previous access() check did ok djm + + OpenBSD-Commit-ID: 875a77dddf0809a3501de2b913cb3bfd4b64f3f7 -commit c21c3a2419bbc1c59cb1a16ea356e703e99a90d9 +commit 2a9e1aadaa20a05430bddc30853fbd3449083a4d Author: djm@openbsd.org -Date: Thu Sep 12 00:36:27 2024 +0000 +Date: Tue Mar 10 03:40:26 2026 +0000 - upstream: Relax absolute path requirement back to what it was prior to + upstream: unveil ssh-pkcs11-helper too; fixes breakage spotted by - OpenSSH 9.8, which incorrectly required that sshd was started with an - absolute path in inetd mode. bz3717, patch from Colin Wilson + anton@ + + If SK/P11/askpass is overridden by environment, only unveil the requested + path and not both the requested one and the default. + + feedback/ok deraadt@ + + OpenBSD-Commit-ID: 84356c6a44f35e66fe73fc1524a7c8e908521eb2 + +commit 46eb7dc5a6f312f99437ebdcf04f0f2c03aa570b +Author: deraadt@openbsd.org +Date: Sat Mar 7 18:35:43 2026 +0000 + + upstream: With it's own daemonization / fd cleaning code, ssh-agent + + opens /dev/null O_RDWR after a pledge without "wpath". This is allowed in + current pledge because "/dev/null" is implicitly allowed to be opened even + with the most restrictive pledges or unveils. This is a design decision in + pledge made at the very beginning, to satisfy libc requirements. We've + finally had enough experience and know how to fix that in the near-future, + but need to review and fix all code which opens these implicit paths. The fix + is to add "wpath", so that "/dev/null" can be opened O_RDWR. But that is + uncomfortable, so we add unveil() allowing "/" with "r", 4 unveil "x" for the + potential askpass and helpers to be execve'd, and "/dev/null" with "wr". As + a result filesystem access is substantially more restricted than before, and + ssh-agent is ready for the future pledge change. ok djm dtucker + + OpenBSD-Commit-ID: f223b11d2db3c0b14e53c1de59966dd5f372a977 + +commit b75bf339eae6115c544bdcefa0d67a6dcc971ec5 +Author: deraadt@openbsd.org +Date: Sat Mar 7 18:27:52 2026 +0000 + + upstream: Stop doing access() before execve(). It is a TOCTOU, but + + also it forces use of unveil "rx" instead of "x". This is done by using a + pipe() through the fork+execve attempt to expose execve failure and create + the same error return as the access() used to do. ok djm dtucker + + OpenBSD-Commit-ID: f9ee96e20352f35dc6f39127e0cc6b804700200a + +commit 73888af650f0ce27cd93797f3e351b2d1b670550 +Author: Damien Miller +Date: Tue Mar 10 14:43:30 2026 +1100 + + stubs for OpenBSD unveil(2) + +commit 4e15f7fc0c0ba897c227350eee1462d635ab32a6 +Author: dtucker@openbsd.org +Date: Fri Mar 6 07:06:45 2026 +0000 + + upstream: Move OpenBSD CVS ID marker to top of file to avoid conflicts + + when syncing changes to portable. + + OpenBSD-Regress-ID: 6b7a9ef354e13e26ed474e98d04ec1d74e56e54e + +commit 2df416dff1a1d5fb31598b7ce8fb5cb6b0f64fd3 +Author: dtucker@openbsd.org +Date: Fri Mar 6 06:57:33 2026 +0000 + + upstream: Replace u_intXX_t types with the equivalent C99 uintXX_t + + types to match similar change to the main ssh code. + + OpenBSD-Regress-ID: a62b6499f784f75a4fcb865aebb83f5936917a91 + +commit e067ccd6b4306ca6422d94ff7ddd231cbddd43cb +Author: djm@openbsd.org +Date: Thu Mar 5 05:44:15 2026 +0000 + + upstream: ssh-agent supports a "query" extension that allows a + + client to request a list of extensions it support. This makes this capability + available to ssh-add via the -Q flag. + + ok markus@ + + OpenBSD-Commit-ID: f211630568ff1a7d6bb4983a94f05ddac1c2d4eb + +commit 4fe278629c3f792628ea71132ba4fcbb9ceaa6b7 +Author: djm@openbsd.org +Date: Thu Mar 5 05:40:35 2026 +0000 + + upstream: With IANA codepoints for draft-ietf-sshm-ssh-agent now + + allocated, it's safe to start using the standard names for requesting agent + forwarding over the @openssh.com extension names we've used to date. + + Support for the standard names is advertised via EXT_INFO. When the + client sees such support it will use the new names preferentially, + but the existing names remain supported unconditionally. + + ok markus@ + + OpenBSD-Commit-ID: 1ab4a0b4de01e81a432875c2b7e5f7357e231af3 + +commit 511f5bc41aeca7f6ee6611e9b24d48e4dd6ae3d5 +Author: djm@openbsd.org +Date: Thu Mar 5 05:35:44 2026 +0000 + + upstream: correctness wrt draft-ietf-sshm-ssh-agent: + + extension requests should indicate failure using + SSH_AGENT_EXTENSION_FAILURE rather than the generic SSH_AGENT_FAILURE + error code. This allows the client to discern between "the request + failed" and "the agent doesn't support this extension". + + ok markus@ + + OpenBSD-Commit-ID: d15d89f210cc973271d68147f09550163df731c9 + +commit 2a387ba37452971747d2f00db7d4c18b4f2c45ed +Author: dtucker@openbsd.org +Date: Tue Mar 3 09:57:25 2026 +0000 + + upstream: Replace all remaining instances of u_intXX_t types with the + + C99 equivalent uintXX_t types. ok djm@ + + OpenBSD-Commit-ID: d9b81151266adb129574ce268af49f14ac23e65b + +commit bb781f02d4efd178e329a62a838962bee16e3e9b +Author: djm@openbsd.org +Date: Mon Mar 2 02:40:15 2026 +0000 + + upstream: Move banner exchange to sshd-auth process + + Previously, exchange of the initial SSH- banners was performed + by the privileged sshd-session monitor. This moves it to the + unprivileged sshd-auth subprocess, removing ~200 LoC from the + monitor's privileged attack surface. + + The monitor gains a new "setcompat" RPC to allow sshd-auth to + inform it of bug compat flags picked up from the client's banner. + + feedback dtucker@, ok markus@ deraadt@ + + OpenBSD-Commit-ID: d767eb1183630d754d521d9f0d84a6c72fbe7fc8 + +commit b50b881b17ab15e34b5e57b159b65f2a02725798 +Author: Darren Tucker +Date: Sun Mar 1 09:46:39 2026 +1100 + + Try -lstdc++ for libcrypto before giving up. + + BoringSSL recently added destructors to libcrypto, which requires + linking against libstdc++, so when checking for a working libcrypto if + at first the link fails, try again with -lstdc++ before giving up. + +commit c26d90e5ad05372b63dbb8727cb6c23a6505a2fb +Author: Darren Tucker +Date: Sun Mar 1 09:41:39 2026 +1100 + + Remove BoringSSL rpath as it's statically linked. + +commit c65f4d2586416274e92720c9e1e745422e182488 +Author: dtucker@openbsd.org +Date: Tue Feb 24 01:50:51 2026 +0000 + + upstream: Use fmprintf instead of logit for challenge-response name and + + info to preserve UTF-8 characters where appropriate. Prompted by github + PR#452, with & ok djm@. + + OpenBSD-Commit-ID: e6361242329ec6925571478f60f4739726aad308 + +commit acf749756872d7555eca48514e5aca6962116fb2 +Author: Darren Tucker +Date: Tue Feb 24 11:28:11 2026 -0500 + + Add AWS-LC and BoringSSL as potential libcryptos. + +commit c25254d1516df5e57affc0e391ed6ead8267b637 +Author: Darren Tucker +Date: Tue Feb 24 11:16:11 2026 -0500 + + Add self-hosted status to main README now it's public. + +commit 5da0ccec2b5806f104913465b62fea475b2e15bb +Author: Darren Tucker +Date: Tue Feb 24 11:10:16 2026 -0500 + + Remove anchor to specific release notes version. + +commit d7a9cd696a316c71e4c16f4158dc516b94abd863 +Author: Darren Tucker +Date: Mon Feb 23 21:34:48 2026 -0500 + + Remove potentially leftover include compat shims. + + If we don't need a specific shim, ensure it does not exist. Prevents + confusion if configurations change or the directory is reused across + different platforms. + +commit c940e709ae2155a4614bc3709e393d88fdddabde +Author: Darren Tucker +Date: Mon Feb 23 20:54:55 2026 -0500 + + Check regress passwd is set before enabling kbdint. + +commit 4ed5f9ecca9ed867c9f1040a3425af35f0703675 +Author: dtucker@openbsd.org +Date: Tue Feb 24 00:39:59 2026 +0000 + + upstream: Remove leftover debugging. + + OpenBSD-Regress-ID: e778d76b21696a14db80f31b9e79601f2d7a9abf + +commit a07a53b00e9aeadb420336783d219be012d88ba1 +Author: Darren Tucker +Date: Mon Feb 23 15:22:10 2026 -0500 + + Activate kbdint test on PAM configs. + +commit 5f98660c51e673f521e0216c7ed20205c4af10ed +Author: Darren Tucker +Date: Wed Feb 18 12:39:31 2026 -0500 + + Install libaudit-dev for --with-audit=linux test. + +commit c9fcea8865b255d4b7566b28dce4af348d2bfbd6 +Author: Darren Tucker +Date: Wed Feb 18 11:22:37 2026 -0500 + + Enable BSM audit test on FreeBSD VMs. + +commit f1a9628cd7e415ce14e157d80c10b61514a22d13 +Author: Darren Tucker +Date: Wed Feb 18 10:59:02 2026 -0500 + + Move BSM audit test to selfhosted runner. + + The vmactions VM on Github does not have the required libraries + installed. + +commit 97e8e66219d036404ae656060f0e0179b61f0614 +Author: Darren Tucker +Date: Wed Feb 18 10:51:09 2026 -0500 + + Increase riscv64 test coverage. + + The machine running the tests has been replaced with a faster one. + +commit e5e18432a27b909aa2194ef0b28a5d49f0e6b3a6 +Author: Darren Tucker +Date: Wed Feb 18 10:49:35 2026 -0500 + + Whitespace fix. + +commit b0463306174941274a1f96eb705618e036832920 +Author: Darren Tucker +Date: Wed Feb 18 09:48:55 2026 -0500 + + Add test coverage for all of the --audit= configs. + +commit 84206bde8adbef2dfe4f5b97dd23399827015333 +Author: djm@openbsd.org +Date: Wed Feb 18 03:04:12 2026 +0000 + + upstream: same treatment for remote/remote copies (i.e. scp -3): + + adjust permissions on destination directory only if we created it or -p was + requested. bz3925 + + OpenBSD-Commit-ID: d977006df7b8330e06ceaa319383b347f1aca3ef + +commit c3631567d9f77c2d073764e4b40f249687f4083e +Author: djm@openbsd.org +Date: Wed Feb 18 02:59:27 2026 +0000 + + upstream: when uploading a directory using sftp/sftp (e.g. during a + + recursive transfer), don't clobber the remote directory permissions unless + either we created the directory during the transfer or the -p flag was set. + bz3925 ok dtucker@ + + OpenBSD-Commit-ID: d66f40d01de05c9ec4029fab5413325301039b3a + +commit 2b0f4a72bd87bef7cc9f0a1889cfc98545cbb158 +Author: djm@openbsd.org +Date: Tue Feb 17 21:45:07 2026 +0000 + + upstream: make IPQoS first-match-wins in sshd_config as it's + + intended to be bz3924 + + OpenBSD-Commit-ID: 42753eb8400ab09713c69ace6fa8bfdde133f942 + +commit 0e35095babe04ba1159e8029133e7f71e53d8fdb +Author: jsg@openbsd.org +Date: Mon Feb 16 23:47:06 2026 +0000 + + upstream: remove duplicate includes; ok dtucker@ + + OpenBSD-Commit-ID: 6b9191bc1a0f4320c926d5ccd9f36b09f0f3bcaf + +commit 9eb778cfde5bca1d84bbad74d8664256301bb13b +Author: Darren Tucker +Date: Mon Feb 16 18:58:04 2026 -0500 + + Restore utf8.h removed earlier as it's needed. + + ... for msetlocale prototype. + +commit 723b76c8a358875cd53376c9a169887ba7a4b088 +Author: Darren Tucker +Date: Mon Feb 16 18:32:41 2026 -0500 + + Removed duplicate includes; spotted by jsg@. + +commit df2b28163ac75e023837de445d6492dc57359105 +Author: Darren Tucker +Date: Sun Feb 15 14:16:56 2026 -0500 + + Remove "draining" of PAM prompts. + + With the previous commit, both prompts and info/error error messages are + returned to keyboard-interactive immedately and none are accumulated, so + there will never be any un-drained prompts. ok djm@ + +commit b9a6dd4d66ee14577494d550b396d0452bf05e1e +Author: Marco Trevisan (Treviño) +Date: Tue Oct 17 04:27:32 2023 +0200 + + auth-pam: Immediately report interactive instructions to clients + + SSH keyboard-interactive authentication method supports instructions but + sshd didn't show them until an user prompt was requested. + + This is quite inconvenient for various PAM modules that need to notify + an user without requiring for their explicit input. + + So, properly implement RFC4256 making instructions to be shown to users + when they are requested from PAM. + + Closes: https://bugzilla.mindrot.org/show_bug.cgi?id=2876 + +commit a1158bba43e00240c00c530596de2d4e1d405b50 +Author: Matthew Heller +Date: Mon Oct 14 09:25:41 2024 -0500 + + fix duplicate PAM msgs, missing loginmsg reset + + without this change in mm_answer_pam_account all messages added in + auth-pam.c sshpam_query(...) case PAM_SUCCESS end up sent here, then are + still sitting in the loginmsg buffer and printed a second time in + session.c do_login(...) + +commit 7a59f55e621c841aab187c96e0f3271c5c799709 +Author: dtucker@openbsd.org +Date: Mon Feb 16 00:45:41 2026 +0000 + + upstream: Reorder headers to match KNF and Portable. + + ID sync only. + + OpenBSD-Commit-ID: b7f9700d07b532eb3720f7bd722b952e31b1752f + +commit c5cee49a0c5721532716365f32977fc02eeea1d5 +Author: dtucker@openbsd.org +Date: Sun Feb 15 22:29:30 2026 +0000 + + upstream: Add basic test for keyboard-interactive auth. + + Not enabled by default since it requires some setup on the host. + + OpenBSD-Regress-ID: aa8a9608a2ea2e5aaa094c5a5cc453e4797cd902 + +commit 07c6413e7bf08b7bfc6fd543eded9da68898e230 +Author: jsg@openbsd.org +Date: Sat Feb 14 00:18:34 2026 +0000 + + upstream: remove unneeded includes; ok dtucker@ + + OpenBSD-Commit-ID: bba6e85492276c30c7a9d27dfd3c4c55fa033335 + +commit d8b806a2e6cd50c729e5d2bad569955a1df33f63 +Author: Darren Tucker +Date: Sun Feb 15 13:31:52 2026 -0500 + + Remove obsolete comment referencing auth-chall.c. + + It was removed in commit 6cb6dcff along with the rest of the SSH1 server + support. + +commit 3e8a45e0eeb5c84f12ac04ea7cc2f831c91c263b +Author: Marco Trevisan (Treviño) +Date: Mon Oct 16 21:15:45 2023 +0200 + + auth-pam: Add an enum to define the PAM done status + + Makes things more readable and easier to extend + +commit 9b0e50b4132679f0c09c0f1272bf1c45959103ea +Author: Marco Trevisan (Treviño) +Date: Tue Oct 17 04:35:17 2023 +0200 + + auth-pam: Add debugging information when we receive PAM messages + +commit c2447697aaecae11d164f1ba30e06d14b5cabcdd +Author: Darren Tucker +Date: Fri Feb 13 15:34:44 2026 -0500 + + Remove DragonFlyBSD workaround for sys/mount.h. + + ... since we're not not including it at all any more. + +commit 8b3a0552054106feb036c632fc844f878568799f +Author: dtucker@openbsd.org +Date: Fri Feb 13 19:06:18 2026 +0000 + + upstream: Replace with + + The former is a portability hassle, but it turns out the only thing we + need from it is PATH_MAX which we can get directly from limits.h. + + OpenBSD-Commit-ID: ccfbbd678bef3a3930ae89da456645c3ee5f83c0 + +commit db475199639667197b12b3aa5205de71ef102e23 +Author: jsg@openbsd.org +Date: Fri Feb 13 01:04:47 2026 +0000 + + upstream: remove unneeded forward struct declaration ok djm@ + + OpenBSD-Commit-ID: a0c97e919667394bef8dbf31df72af3ba07542e9 + +commit ae51e05dbd840ad674fee754f33c0e2fd141074e +Author: djm@openbsd.org +Date: Wed Feb 11 22:58:23 2026 +0000 + + upstream: very basic testing of multiple files in RevokedKeys and + + RevokedHostkeys + + OpenBSD-Regress-ID: 6cee76bcc4bd6840bc8d39dd0d32d724e1427aa7 + +commit 2f51e29b9a0ffd7acb9dc70d90defa466b5695d4 +Author: djm@openbsd.org +Date: Wed Feb 11 22:57:55 2026 +0000 + + upstream: support multiple files in a ssh_config RevokedHostKeys + + directive bz3918; ok dtucker + + OpenBSD-Commit-ID: 0ad2eacf836f912f347846ab84760799033dd348 + +commit 135a62238a479c7369f2b2d5dafb921ddc1c2b74 +Author: djm@openbsd.org +Date: Wed Feb 11 22:57:16 2026 +0000 + + upstream: support multiple files in a sshd_config RevokedKeys + + directive bz3918; ok dtucker + + OpenBSD-Commit-ID: 9fc58c4e676f8e9ed2e3a0da666242a17b8a55b2 + +commit 3160f2a97e875bfa9454f98899cbccad48c96ff4 +Author: dtucker@openbsd.org +Date: Wed Feb 11 17:05:32 2026 +0000 + + upstream: Add includes used in Portable to reduce diffs. + + OpenBSD-Commit-ID: 186c60cf2da0ddb075d5bc4879e87bbd8779b7e4 + +commit 6a756f3f7b9f87f24e948ec1de0266f5c1587811 +Author: dtucker@openbsd.org +Date: Wed Feb 11 17:03:17 2026 +0000 + + upstream: Remove unused sys/queue.h include. + + OpenBSD-Commit-ID: 564f75672e27f1006f280614934eb304abe69167 + +commit c169300df12b9aa7005ff6e61880a7e007e83bc5 +Author: dtucker@openbsd.org +Date: Wed Feb 11 17:01:34 2026 +0000 + + upstream: Reorder includes and defines to match both KNF and + + Portable. + + OpenBSD-Commit-ID: f3f179c095f8e4787ded5f450e2842881f6b8ab2 + +commit 1a4eb511abaf3522b84fa5697524b81b4865279b +Author: Darren Tucker +Date: Wed Feb 11 17:36:42 2026 -0500 + + Factor out RNG reseeding in to a single function. + + sshd and sshd-session both reseed the RNG after a fork. Move the + existing reseed_prngs() function into entropy.c and use for both. + Clean up entropy.h too. ok djm@ + +commit 81746188e9333b166b4c31f9654d8eb249ddd897 +Author: Darren Tucker +Date: Wed Feb 11 16:47:27 2026 -0500 + + Remove do_pam_chauthtok since it's no longer used. + +commit f1b9e0f7f1f1ed5be2bd1c39bda03fc99a1cf5d8 +Author: dtucker@openbsd.org +Date: Wed Feb 11 16:57:38 2026 +0000 + + upstream: Pass actual size of the buffer to hostname() instead of a + + define that's probably the same. ok millert@ djm@ + + OpenBSD-Commit-ID: 7c97b22439100b4193404ccfa1e5f539c5a8d039 + +commit 4ef24496b7c4c918d4d3a049f83739fbe2e36e9f +Author: dtucker@openbsd.org +Date: Mon Feb 9 22:15:45 2026 +0000 + + upstream: De-underscore __inline__ to match -portable + + (and every other use of it in ssh). ID sync only. + + OpenBSD-Commit-ID: 83c913d5e2345635bc5434167ed67cec5409d494 + +commit c8972792e5ce599e584bbe1aa084cc4056f1afe5 +Author: dtucker@openbsd.org +Date: Mon Feb 9 22:12:48 2026 +0000 + + upstream: Remove references to skey auth which is long gone. + + ID sync only. + + OpenBSD-Commit-ID: 0c2340566c399f7f74fe4c5366394974cd6fd122 + +commit db779679839d2798de7cda196a3fe750a12845e8 +Author: dtucker@openbsd.org +Date: Mon Feb 9 22:11:39 2026 +0000 + + upstream: Remove unused OpenSSL includes, + + that are no longer used, even when building with OPENSSL=yes. + + OpenBSD-Commit-ID: e97e3e551ade9aee994b80a1d5851be6f32288e3 + +commit 8ec21f6274108e93601173ec4e6f7528b90b0003 +Author: dtucker@openbsd.org +Date: Mon Feb 9 22:09:48 2026 +0000 + + upstream: Use https for URLs. + + ID sync only. + + OpenBSD-Commit-ID: 85b2919e95e6d2bfdeddf5e3b0709fb5b6b4c438 + +commit c3eaa953ae78e581d7ba2327beea35206a14bc1e +Author: dtucker@openbsd.org +Date: Mon Feb 9 21:38:14 2026 +0000 + + upstream: Remove unused OpenSSL includes, + + which are no longer used even when building with OPENSSL=yes. + + OpenBSD-Commit-ID: 31adb21bf3f8f5c13cde59229f1b85c20f19a858 + +commit 280cf58afe71bf34141e732d30676367f0150bbe +Author: dtucker@openbsd.org +Date: Mon Feb 9 21:23:35 2026 +0000 + + upstream: Remove now-unused SKEYQUERY enums from monitor_reqtype. + + ID sync only. + + OpenBSD-Commit-ID: dab93b58e69c754887507e5557a81a0b5b84d734 + +commit bb2703365ede3b4e13fdfa1c250ac88408e75f38 +Author: dtucker@openbsd.org +Date: Mon Feb 9 21:21:39 2026 +0000 + + upstream: Remove now-unused openssl includes since sshd.c no longer + + needs them, even when built with OpenSSL. + + OpenBSD-Commit-ID: ceaa0394db1520e92d75c37eea58130d44ba93c9 + +commit 8a5d591c9f42933c49ece95e49c116d684d6cca0 +Author: Darren Tucker +Date: Wed Feb 11 11:38:58 2026 -0500 + + Don't create sys/mount.h shim except on DragonFly. + + Fixes build on Mac OS X. + +commit 957cb0fbe87b6ab76045e8dc99426db6afb54057 +Author: Darren Tucker +Date: Tue Feb 10 08:55:53 2026 +1100 + + Minor resync with upstream + + Reorder definitions add whitespace to eliminate diffs vs upstream. + +commit 4922635d3e66f9107c5b68a0a3fa57ddf0d820ae +Author: Darren Tucker +Date: Tue Feb 10 07:22:30 2026 +1100 + + Factor out COMPATINCLUDES into its own variable. + +commit 3e9c4ed3b0e5d3890fcd2cbc9c3b595f17ea1946 +Author: Darren Tucker +Date: Tue Feb 10 05:34:46 2026 +1100 + + Provide compat shims for sys/{mount.h,statvfs.h). + + In addition to shimming on platforms that don't have them, we also need to + shim sys/mount.h on DragonFlyBSD since it uses its native STAILQ_ENTRYs + which our compat queues.h does not have, which causes sftp-server.o to + not build. This is a little icky, but it limits the blast radius to + just one source file on only DragonFly. ok djm@ + +commit eeb671fa2f0fd7dda4c6b726098fe28016dc185b +Author: Darren Tucker +Date: Tue Feb 10 03:39:45 2026 +1100 + + Shim and . + + This significantly reduces the diff vs upstream making future syncs + less painful. ok djm@ + +commit 47828dbd95c095d0cad327e12bb6859a510833c8 +Author: dtucker@openbsd.org +Date: Sun Feb 8 19:54:31 2026 +0000 + + upstream: Reorder headers according to KNF, + + and pull in a few we don't have from Portable. + + OpenBSD-Commit-ID: d83f6c75da7bfb16bbff40fd2133d6eba4aba272 + +commit c73b8b09bf43be3dfe14bc0da349b352b280a74a +Author: dtucker@openbsd.org +Date: Sun Feb 8 17:51:43 2026 +0000 + + upstream: Include sys/socket.h to match -portable, + + eliminating one diff. + + OpenBSD-Commit-ID: 7670fdf35b0c7aee41cd0d6ded86b4792e261f36 + +commit 9385d72dd36ba6050b5f7728c14e3edc8329fe95 +Author: dtucker@openbsd.org +Date: Sun Feb 8 17:50:49 2026 +0000 + + upstream: Reorder headers as per KNF. + + OpenBSD-Commit-ID: 3e29fabe20422454fd5d77f85c853e1e557f2181 + +commit 62439369181b9b1dabf1ec3c2de6a7fbfcfb45eb +Author: Darren Tucker +Date: Mon Feb 9 06:56:35 2026 +1100 + + Remove openindiana VM test. + + When it works it's by far the slowest (>1h to install packages) and the + package installation is flaky. We can bring it back if their infra ever + improves. + +commit 43d0bf02d84a20a3f7c9992dabf8c109d9c25bed +Author: Darren Tucker +Date: Mon Feb 9 06:42:27 2026 +1100 + + Sync header order with upstream and KNF. + +commit a3742cc38a6aa48a653a1a6300bc825f083955af +Author: Darren Tucker +Date: Mon Feb 9 06:41:07 2026 +1100 + + Sync whitespace with upstream. + +commit b62198a19a53227ca166c62825ac72a7696c42ed +Author: Darren Tucker +Date: Mon Feb 9 05:02:36 2026 +1100 + + Sync header order with upstream. + +commit 98fdb05f0c0d7a89a066225a94eafd7fce10163d +Author: Darren Tucker +Date: Mon Feb 9 04:09:26 2026 +1100 + + Remove generic check for getpagesize. + + We have a more specific check later. + +commit 249476f45dba9a92056bd2935aae7429f0f3b17c +Author: Darren Tucker +Date: Mon Feb 9 03:47:25 2026 +1100 + + Test KERBEROS5=yes builds on OpenBSD. + +commit 6adb65508efc2def558f50a56c5eada09ca500c9 +Author: dtucker@openbsd.org +Date: Sun Feb 8 15:28:01 2026 +0000 + + upstream: Make ssh optionally build with Kerberos 5 against the + + Heimdal port. This updates the Makefiles and repairs some bitrot in headers, + resyncing them against Portable. To do this, "pkg_add heimdal" then "make + KERBEROS5=yes". ok djm@ + + (ID sync only) + + OpenBSD-Commit-ID: 31f95c9ba58aa7ba89264f1d80c79106042b1095 + +commit d6c672a8c16c8962e6b3022e279441fa6630cb86 +Author: dtucker@openbsd.org +Date: Sun Feb 8 03:30:15 2026 +0000 + + upstream: Remove sys/poll.h since we also have poll.h. + + Also removes one line of diff vs portable. + (ID sync only). + + OpenBSD-Commit-ID: 461bd0cd35bfad82bd06892ccb0ff0fac15d1d27 + +commit 8605ed26334b9ae704b8abe51940b61bdfe1e974 +Author: dtucker@openbsd.org +Date: Sun Feb 8 00:16:34 2026 +0000 + + upstream: Move setting of user, service and style earlier since + + -portable needs to use these when setting up PAM. Removes two diffs vs + portable. + + OpenBSD-Commit-ID: 8db130d42a3581b7a1eaed65917673d4474fc4fe + +commit ecaaa4f9e44764e55c152a84af3d7efb63c50ce7 +Author: Darren Tucker +Date: Sun Feb 8 11:30:21 2026 +1100 + + Move USE_SYSTEM_GLOB into a glob.h compat shim. + + This moves the logic for selecting whether or not we can use the system + glob into configure, and if either don't have glob or can't use it, we + create the shim. Removes several diffs vs upstream. + +commit 2a1a257612b7c6bcacd934149146a3da7411c485 +Author: dtucker@openbsd.org +Date: Sat Feb 7 18:04:53 2026 +0000 + + upstream: misc.h is needed for ForwardOptions in servconf.h. + + OpenBSD-Commit-ID: b241d81c499e273fc2d81c82d5b7c7b280827416 + +commit ad632364fb06f3bd1e9177e587d0040cf7958676 +Author: Jonas 'Sortie' Termansen +Date: Sat Nov 2 22:30:07 2024 +0100 + + Remove unused includes. + + netinet/in_systm.h is no longer in upstream and anything that actually + needs it will get it from includes.h. + +commit 9ebce88be9d88605e02551fe7f65ef6a16f72667 +Author: dtucker@openbsd.org +Date: Sat Feb 7 17:10:34 2026 +0000 + + upstream: Also check for EWOULDBLOCK on system error. This is the + + same as EAGAIN on OpenBSD so is a no-op but removes a diff making portable + syncs easier. (ID sync only). + + OpenBSD-Commit-ID: 68a5dcc5e2a506208c40396c6366f67bbf3b1dbe + +commit ccc1faf67df795d5cd757df754703823d0874028 +Author: dtucker@openbsd.org +Date: Sat Feb 7 17:04:22 2026 +0000 + + upstream: Move ssherr.h to where portable needs it. + + (ID sync only) + + OpenBSD-Commit-ID: 0488ce85f24864186678dcac7c9973ca44bd2cd5 + +commit 6decbb90413c67c10ac2fd5b17a9c161196641ea +Author: Darren Tucker +Date: Sun Feb 8 04:30:40 2026 +1100 + + Move paths.h and poll.h includes to resync with upstream. + +commit 4fe79e3deb5457af588ab67ee5db642afedd935f +Author: Darren Tucker +Date: Sun Feb 8 04:28:28 2026 +1100 + + Move poll.h include to resync with upstream. + +commit 9e585f11bb71115fb0376b2b6118892ab600aa4f +Author: Darren Tucker +Date: Sun Feb 8 04:25:42 2026 +1100 + + Resync minor format diffs with upstream. + +commit 3fd88caa36a94d85ae66bff297142606d08decde +Author: Darren Tucker +Date: Sun Feb 8 03:56:15 2026 +1100 + + Resync headers with upstream. + +commit 77e41d0c1c8801c553b43eef5974268425395667 +Author: Darren Tucker +Date: Sun Feb 8 03:52:31 2026 +1100 + + Resync with upstream (unused header and whitespace). + +commit a393759f9693a08a7fba18d4824b74f2dda1fe3d +Author: Artem Savkov +Date: Tue Nov 18 16:26:11 2025 +0100 + + Fix ut_type for btmp records + + According to man utmp ut_type is supposed to be only switched from + LOGIN_PROCESS to USER_PROCESS after succesfull authentication and this + is how sshd behaved before 671c44078. + + Fixes: 671c44078 ("use construct_utmp to construct btmp records") + Signed-off-by: Artem Savkov + +commit 15fe1ceb29760d72398c6ac7df5a403416cba207 +Author: djm@openbsd.org +Date: Sat Feb 7 02:02:00 2026 +0000 + + upstream: bit of webauthn support missed in previous commit + + OpenBSD-Commit-ID: 9768454543ded01b7c61567fc5b3e78664346be2 + +commit 670f7d210ceae59db73b16b67e52d8fd8def3012 +Author: dtucker@openbsd.org +Date: Fri Feb 6 23:39:14 2026 +0000 + + upstream: Adjust Makefiles to include just-added + + ssherr_libcrypto where necessary. + + OpenBSD-Regress-ID: 53d179a2db3ab931f2aa0e5447cf20cb9787a8bb + +commit 9c4949c11d8da1a5422e2174afb1a4f5b3dc8914 +Author: dtucker@openbsd.org +Date: Fri Feb 6 23:31:29 2026 +0000 + + upstream: Fetch the error reason from libcrypto + + if available, append it to the corresponding ssh error message and + optionall print the libcrypto full error stack (at debug1). with & + ok tb@ djm@ millert@ schwarze@ + + Note that the quality of errors obtainable from libcrypto is somewhat + variable, so these may be any of: useful, misleading, incomplete + or missing entirely. As a result we reserve the right to change + what is returned or even stop returning it if it does more harm than + good. + + OpenBSD-Commit-ID: 1ad599ac3eeddbe254fec6b9c1cf658fa70d572e + +commit 5b12d836e7c42c146ac1a69a9600db05282dbbb8 +Author: THE-Spellchecker +Date: Sat Jan 3 22:11:39 2026 -0600 + + Typographical Fixes + +commit 11600929832e04aa6ad20a57af7187c3feb973d4 +Author: dtucker@openbsd.org +Date: Fri Feb 6 22:59:18 2026 +0000 + + upstream: Typo fixes, mostly in comments. + + From THE-Spellchecker via github PR#620. + + OpenBSD-Commit-ID: 64929fafa3caae5a162f23257917ecf33f8a3764 + +commit b83c0bb5109eb245dd4f06e4af4a960f96a0c193 +Author: Darren Tucker +Date: Sat Feb 7 06:58:59 2026 +1100 + + Enable gss-auth tests on Kerberos test configs. + +commit d84dbccee4371ce395d28543f146e7b62d8c0d36 +Author: Pavol Žáčik +Date: Thu Jan 29 11:01:19 2026 +0100 + + Add a GSSAPI authentication test + +commit 86e0f4aa2c72d5e96618f0c7214109f5a46ca70d +Author: Darren Tucker +Date: Thu Jan 1 21:41:10 2026 +1100 + + Split sudo out to its own install line. + +commit dfbb8526b5006cfe368193fb15e16f58cce6e1d1 +Author: Darren Tucker +Date: Wed Dec 31 16:35:29 2025 +1100 + + Remove obsolete comments. + +commit f0b7ecf7f5976c11f8c89ee9b0ca19383b573764 +Author: Darren Tucker +Date: Wed Dec 31 16:26:23 2025 +1100 + + Run tests on older OmniOS version too. + +commit 01bddc0663e5239df9342fcf7b373e5f58ff1b49 +Author: Darren Tucker +Date: Wed Dec 31 16:25:16 2025 +1100 + + Add OpenIndiana VM test target. + +commit 91c4d422cc0af2ae592f5e6c0cc505a5d8d7a6d2 +Author: djm@openbsd.org +Date: Fri Feb 6 01:24:36 2026 +0000 + + upstream: remove vestige of when we supported running without privsep + + OpenBSD-Commit-ID: 5342c24d2330ef5ce357c294056f72b8123122c0 + +commit 6463960c58cd0adcb26bfbddceb9d4efcfbd9dd0 +Author: djm@openbsd.org +Date: Thu Feb 5 22:05:49 2026 +0000 + + upstream: Implement missing pieces of FIDO/webauthn signature support, + + mostly related to certificate handling and enable acceptance of this + signature format by default. bz3748 GHPR624 GHPR625 + + Feedback tb / James Zhang; ok tb + + OpenBSD-Commit-ID: ce3327b508086b24a3f7a6507aa5c49d8e9505e6 + +commit 832a77000abe61f61bddb9e595f45c7131c0269d +Author: djm@openbsd.org +Date: Tue Jan 27 06:48:29 2026 +0000 + + upstream: Implement "query" extension from + + draft-ietf-sshm-ssh-agent + + feedback jsg@, tb@; ok tb@ + + OpenBSD-Commit-ID: adb2b79473ff86ba781ed5ab2735c1437b590f07 + +commit 409dc952ab88b5232e809e34fd55662c6f75ad81 +Author: millert@openbsd.org +Date: Thu Jan 22 15:30:07 2026 +0000 + + upstream: Make it clear that DenyUsers/DenyGroups overrides + + AllowUsers/AllowGroups. Previously we specified the order in which the + directives are processed but it was ambiguous as to what happened if both + matched. OK djm@ + + OpenBSD-Commit-ID: 6ae0ab52ff796b78486b92a45cd7ec9310e20f4e + +commit d7950aca8eacae8b889d92c669e913111af75984 +Author: djm@openbsd.org +Date: Wed Jan 21 23:58:20 2026 +0000 + + upstream: In ssh(1), don't try to match certificates held in an + + agent to private keys. + + This matching is done to support certificates that were + loaded without their private key material, but is unnecessary for + agent-hosted certificate which always have private key material + loaded in the agent. Worse, this matching would mess up the + request sent to the agent in such a way as to break usage of these + keys when the key usage was restricted in the agent. + + Patch from Thibault Cools via bz3752, ok dtucker@ + + OpenBSD-Commit-ID: ebfe37817dad4841c53339930565242ec683d726 + +commit b0d0b71651b5a19d0dbd27b623ebb4fc43145560 +Author: sthen@openbsd.org +Date: Wed Jan 21 15:44:51 2026 +0000 + + upstream: If editline has been switched to vi mode (i.e. via "bind + + -v" in .editrc), setup a keybinding so that command mode can be entered. Diff + originally from Walter Alejandro Iglesias with tweaks. Feedback from Crystal + Kolipe. ok djm + + OpenBSD-Commit-ID: 5786e17ccd83573e2d86418023f9bc768223336a + +commit 1cc936b2fabffeac7fff14ca1070d7d7a317ab7b +Author: dtucker@openbsd.org +Date: Tue Jan 20 22:56:11 2026 +0000 + + upstream: Fill entropy in a single operation instead of hundreds. + + The sntrup761 code we use from SUPERCOP fills entropy arrays 4 bytes at + a time. On some platforms each of these operations has a significant + overhead, so instead fill it in a single operation and as a precaution + zero that array after it's used. + + Analysis and code change is from Mike Frysinger via Github PR#621 with + feedback from djm@ and sed-ification from me. ok djm@ beck@. + + This change was submitted by Mike to SUPERCOP upstream so hopefully + future versions will already have it. + + OpenBSD-Commit-ID: 0e85c82f79b1b396facac59e05b288c08048f15c + +commit a6f8f793d427a831be1b350741faa4f34066d55f +Author: djm@openbsd.org +Date: Sun Jan 4 09:52:58 2026 +0000 + + upstream: rewrite SOCKS4/4A/5 parsing code to use sshbuf functions + + instead of manual pointer fiddling. Should make the code safer and easier to + read. feedback/ok markus@ + + OpenBSD-Commit-ID: 5ebd841fbd78d8395774f002a19c1ddcf91ad047 + +commit ea367b4bbc3fd49f84683763723425adfdce35c0 +Author: djm@openbsd.org +Date: Tue Dec 30 04:28:42 2025 +0000 + + upstream: test the right thing, doofus + + OpenBSD-Commit-ID: 31b2ec6e0b3dbd08c60ba2d969dd687cd80c25fd + +commit 5f2bc9cb8625d1fd582e0e4b562200f9856f1f7d +Author: djm@openbsd.org +Date: Tue Dec 30 04:23:53 2025 +0000 + + upstream: avoid possible NULL deref if + + ssh_packet_check_rekey_blocklimit() called before the encrypted transport is + brought up. + + OpenBSD-Commit-ID: fb998ccbe59865e33a8ab6a6577f254d39bdc72f + +commit b9c318777eb40db66fb92df87666c3642467d0e7 +Author: djm@openbsd.org +Date: Tue Dec 30 00:12:58 2025 +0000 + + upstream: unit tests for sshbuf_consume_upto_child() + + OpenBSD-Regress-ID: 13cbd0370ebca7c61c35346b3e0356517719a447 + +commit dd49a87bf4e4a219978bf20f03e2a72041f57b2f +Author: djm@openbsd.org +Date: Tue Dec 30 00:35:37 2025 +0000 + + upstream: Remove bug compatibility for implementations that don't + + support rekeying. AFAIK this is only an ancient Sun SSH version. + + If such an implementation tries to interoperate with OpenSSH, it + will eventually fail when the transport needs rekeying. + + This is probably long enough to use it to download a modern SSH + implementation that lacks this problem :) + + ok markus@ deraadt@ + + OpenBSD-Commit-ID: 228a502fee808cf8b7caee23169eb6a1ab1c331a + +commit ca313fef2deed90668fe0706da8529310092d1dd +Author: djm@openbsd.org +Date: Tue Dec 30 00:22:58 2025 +0000 + + upstream: Enforce maximum packet/block limit during + + pre-authentication phase + + OpenSSH doesn't support rekeying before authentication completes to + minimise pre-auth attack surface. + + Given LoginGraceTime, MaxAuthTries and strict KEX, it would be + difficult to send enough data or packets before authentication + completes to reach a point where rekeying is required, but we'd + prefer it to be completely impossible. + + So this applies the default volume/packet rekeying limits to the + pre-auth phase. If these limits are exceeded the connection will + simply be closed. + + ok dtucker markus + + OpenBSD-Commit-ID: 70415098db739058006e4ebd1630b6bae8cc8bf6 + +commit 55b6b1697433eca98052f5c45281133ca793a9c8 +Author: djm@openbsd.org +Date: Mon Dec 29 23:52:09 2025 +0000 + + upstream: Add sshbuf_consume_upto_child(), to similify particular + + parsing patterns using parent/child buffer; ok markus@ + + OpenBSD-Commit-ID: c11ed27907751f2a16c1283313e77f88617e4852 + +commit 6eafc52a4185ba6d765047146cd645152baaeb58 +Author: Ludovic Rousseau +Date: Sat Dec 27 10:07:22 2025 +0100 + + Update ssh-agent.1 + + Add a missing "/" in the default allowed providers list. + +commit 09daf2ac5f248dc5d60a6f3a703b479d67da14b4 +Author: djm@openbsd.org +Date: Mon Dec 22 03:36:43 2025 +0000 + + upstream: correctly quote wildcard host certificate principal name, + + lest it expand to an unrelated filename in the working directory + + OpenBSD-Regress-ID: 8a9eb716d3ea7986d26c1a931758b996aa93c58e + +commit dfd710e4e2928201743e32027e2d6cf0e2eafc61 +Author: djm@openbsd.org +Date: Mon Dec 22 03:12:05 2025 +0000 + + upstream: return 0 in void function; spotted by clang -Wextra + + OpenBSD-Commit-ID: fe7461c93dfaef98a007a246af837a8275a1e539 + +commit ecdf9b9f8e89aae65d4a12fe5a25c560eea08393 +Author: djm@openbsd.org +Date: Mon Dec 22 01:50:46 2025 +0000 + + upstream: regression tests for certificates with empty principals + + sections (which are now unconditionally refused) and for certificates with + wildcard principals (which should only be accepted in host certs) + + OpenBSD-Regress-ID: fdca88845a68424060547b4f9f32f90a7cf82e73 + +commit adca2f439827eb829652805f36e288b5b260ce1b +Author: djm@openbsd.org +Date: Mon Dec 22 01:31:07 2025 +0000 + + upstream: don't try to test webauthn signatures. Nothing in OpenSSH + + generates these (yet) + + OpenBSD-Regress-ID: 48d59b7c4768c2a22ce3d8cf3b455e6ada9fc7b0 + +commit 5166b6cbf2b6103117a79f90a68068e89e02bf66 +Author: djm@openbsd.org +Date: Mon Dec 22 01:49:03 2025 +0000 + + upstream: When certificate support was added to OpenSSH, + + certificates were originally specified to represent any principal if the + principals list was empty. + + This was, in retrospect, a mistake as it created a fail-open + situation if a CA could be convinced to accidentally sign a + certificate with no principals. This actually happened in a 3rd- + party CA product (CVE-2024-7594). + + Somewhat fortunately, the main pathway for using certificates in + sshd (TrustedUserCAKeys) never supported empty-principals + certificates, so the blast radius of such mistakes was + substantially reduced. + + This change removes this footcannon and requires all certificates + include principals sections. It also fixes interpretation of + wildcard principals, and properly enables them for host + certificates only. + + This is a behaviour change that will permanently break uses of + certificates with empty principals sections. + + ok markus@ + + OpenBSD-Commit-ID: 0a901f03c567c100724a492cf91e02939904712e + +commit aaac8c61c18124eb5fb8a2cff1e85dea2db6c147 +Author: djm@openbsd.org +Date: Mon Dec 22 01:20:39 2025 +0000 + + upstream: Don't misuse the sftp limits extension's open-handles + + field. This value is supposed to be the number of handles a server will allow + to be opened and not a number of outstanding read/write requests that can be + sent during an upload/download. + + ok markus@ + + OpenBSD-Commit-ID: 14ebb6690acbd488e748ce8ce3302bd7e1e8a5b0 + +commit daf6bdd34b59f640d2af0fd230da69f1cbad33b4 +Author: djm@openbsd.org +Date: Mon Dec 22 01:17:31 2025 +0000 + + upstream: add a "ssh -O channels user@host" multiplexing command to + + get a running mux process to show information about what channels are + currently open; ok dtucker@ markus@ + + OpenBSD-Commit-ID: 80bb3953b306a50839f9a4bc5679faebc32e5bb8 + +commit b652322cdc5e94f059b37a8fb87e44ccb1cdff33 +Author: djm@openbsd.org +Date: Fri Dec 19 01:27:19 2025 +0000 + + upstream: typo in comment + + OpenBSD-Commit-ID: f72306b86953e74f358096db141b4f9c00d33ed7 + +commit 0b98be75dbb2ccb1c3146429c0077416c113b57d +Author: djm@openbsd.org +Date: Fri Dec 19 01:26:39 2025 +0000 + + upstream: correctly check subsystem command is not the empty string + + (was repeatedly checking the subsystem name) spotted by Coverity (CID 898836) + + OpenBSD-Commit-ID: dabea2b499de8280f76f7291dd52086df6831cb0 + +commit 345892ba2e8efea4be03675c866395bee251c117 +Author: djm@openbsd.org +Date: Fri Dec 19 00:57:42 2025 +0000 + + upstream: regression test for bz3906: sshd crashing at connection + + time if the config lacks a subsystem directive but one is defined in a match + block. + + OpenBSD-Regress-ID: 5290553665307ccddaec2499ec1eb196bb2efc84 + +commit 81e5bb8d93f2d8361bd7f4b034044ad8ee4ded0e +Author: djm@openbsd.org +Date: Fri Dec 19 00:48:47 2025 +0000 + + upstream: check that invalid subsystem directives inside Match + + blocks are noticed at startup; bz#3906 + + OpenBSD-Regress-ID: b9171bde4cc24757a826b3da0e9eadc33995a453 + +commit 831e6db69ff8625b6e81c2809aa082abbab6c0b1 +Author: djm@openbsd.org +Date: Fri Dec 19 00:56:34 2025 +0000 + + upstream: don't crash at connection time if the main sshd_config + + lacks any subsystem directive but one is defined in a Match block + + bz#3906; ok dtucker + + OpenBSD-Commit-ID: 2eb9024726d6f10eaa41958faeca9c9ba5ca7d8a + +commit 4e0f2dee54d210dc44f72f73e703c6dc5348a406 +Author: djm@openbsd.org +Date: Fri Dec 19 00:48:04 2025 +0000 + + upstream: detect invalid sshd_config Subsystem directives inside + + Match blocks at startup rather than failing later at runtime; + + noticed via bz#3906; ok dtucker + + OpenBSD-Commit-ID: e6035ff0baa375de6c9f22c883ed530a8649dfed + +commit 4c9de155ce1d35c9e3c05223cc093580f9efff9a +Author: jsg@openbsd.org +Date: Thu Dec 18 23:54:10 2025 +0000 + + upstream: new sentence, new line + + OpenBSD-Commit-ID: 23974d7c98b2ba4fea7f5143676c34e04ffd4128 + +commit 3ab346aa6d9030379df3ec1ed0b0ce608f952c5f +Author: jsg@openbsd.org +Date: Thu Dec 18 23:51:56 2025 +0000 + + upstream: fix markup, .CM -> .Cm + + OpenBSD-Commit-ID: 4db8cb254792df8a4dce11825852e089ae3d053a + +commit f878d7ccc25b02a39e6766f5dd405d5de6fb106c +Author: dtucker@openbsd.org +Date: Tue Dec 16 08:36:43 2025 +0000 + + upstream: Plug leak in ssh_digest_memory on error path. + + Bonehead mistake spotted by otto@, ok djm@ + + OpenBSD-Commit-ID: 4ad67ac402e0b4c013f4f4e386d22b88969a5dd7 + +commit 49480f1934f8cf994afa646d4bcbd22ac08bb6af +Author: dtucker@openbsd.org +Date: Tue Dec 16 08:32:50 2025 +0000 + + upstream: Add 'invaliduser' penalty to PerSourcePenalties, which is + + applied to login attempts for usernames that do not match real accounts. + Defaults to 5s to match 'authfail' but allows administrators to block such + sources for longer if desired. with & ok djm@ + + OpenBSD-Commit-ID: bb62797bcf2adceb96f608ce86d0bb042aff5834 + +commit 94bf1154b4132727114f222a587daeac101f1f5b +Author: djm@openbsd.org +Date: Mon Dec 8 03:55:22 2025 +0000 + + upstream: add a GssDelegateCreds option for the server, controlling + + whether it accepts delgated credentials offered by the client. This option + mirrors GssDelegateCreds in ssh_config. + + From Dmitry Belyavskiy via GHPR614; ok dtucker@ + + OpenBSD-Commit-ID: ac419354edb26cef9ad15692e0bed17a03997786 + +commit 24f32f7755801b16368375b8e27fb1a48d250fc5 +Author: djm@openbsd.org +Date: Mon Dec 8 00:45:00 2025 +0000 + + upstream: errant line + + OpenBSD-Commit-ID: 8542d59f5ba48a67c3ebd5de17f9fa408ec54ca5 + +commit a1e37f0998ed5027f6c8dd30befb379ea2cac95b +Author: djm@openbsd.org +Date: Mon Dec 8 00:44:16 2025 +0000 + + upstream: There is a warning next to the authorized_keys command="" + + flag that forcing a command doesn't automatically disable forwarding. Add one + next to the sshd_config(5) ForceCommand directive too. + + feedback deraadt@ + + OpenBSD-Commit-ID: bfe38b4d3cfbadbb8bafe38bc256f5a17a0ee75c + +commit 70ad2e9a2b3aa6f856200464078c2750bfba0e3d +Author: djm@openbsd.org +Date: Mon Dec 8 00:41:46 2025 +0000 + + upstream: increment correct variable when counting group + + memberships. Reported by Kevin Day via bz3903 + + OpenBSD-Commit-ID: 772b9aafd5165a7c407f08cb95f8b94cc5a4c1c0 + +commit d05b704086d53c02f4ad7de921435f7e7e3ad60a +Author: Darren Tucker +Date: Sun Dec 7 20:10:42 2025 +1100 + + Add OpenBSD 7.8 VM test target. + +commit f086fafa0486012df6ba095664be75ecbf68e8e1 +Author: Darren Tucker +Date: Sun Dec 7 13:43:02 2025 +1100 + + Remove generated compat includes during distclean. + +commit 185459dd87c4f7580a2591fbbbb1d800ec249b78 +Author: Darren Tucker +Date: Sun Dec 7 14:17:20 2025 +1100 + + Define IPTOS_DSCP_VA if not already defined. + +commit f701869185915b9a324dcc23c12d0035251ef93f +Author: phessler@openbsd.org +Date: Fri Dec 5 17:48:47 2025 +0000 + + upstream: allow network programs select DSCP_VA for network ToS + + OK stsp@ + + OpenBSD-Commit-ID: 8019fd6e8c522b4b5f291a2c0e3bf2437cc70dc1 + +commit f62868e03e51785c521c4d20d60662c0bbdd695e +Author: dtucker@openbsd.org +Date: Sun Dec 7 02:59:53 2025 +0000 + + upstream: Avoid "if ! thing || ! otherthing; then" constructs since + + they seem to cause portability problems. + + OpenBSD-Regress-ID: ff001be683de43bf396cd5f9f6a54e0c7a99c3cf + +commit 45aca67d79c194660342a64a9175d814d4e8ba56 +Author: dtucker@openbsd.org +Date: Sun Dec 7 02:49:41 2025 +0000 + + upstream: spaces->tab + + OpenBSD-Regress-ID: c78eb430da0ec2c4b6919ff4d27ef8e565ef52ff + +commit ab164f671609a3a25cd0efcd967aff29144081bb +Author: dtucker@openbsd.org +Date: Sat Dec 6 07:10:24 2025 +0000 + + upstream: Append a newline, otherwise some sed's won't output anything. + + OpenBSD-Regress-ID: 507cb8c36bb7fc338f60a55bf7040f479536b3f7 + +commit c99a30d30a5d2af6fec30b9b0d85aa9b252760c9 +Author: dtucker@openbsd.org +Date: Sat Dec 6 03:23:27 2025 +0000 + + upstream: Don't check compressions stats when ssh does not support + + compression. + + OpenBSD-Regress-ID: 026db51b2654a949e9a10b908443dab83b64c74a + +commit 5f5d1af478d4b9daf61fab1e4298973980d4c348 +Author: djm@openbsd.org +Date: Fri Dec 5 11:13:35 2025 +0000 + + upstream: ASSERT_DOUBLE_* test helpers + + OpenBSD-Regress-ID: cdb5c4e95c0f00efb773ddba4056a49e33702cf9 + +commit 70a01a7e66075047329e3aeccc942678f512ebdd +Author: Darren Tucker +Date: Fri Dec 5 20:02:39 2025 +1100 + + Set SSH_REGRESS_TMP after making tmpdir. + + Put both of these later in the script so the cvsids don't cause + conflicts on every synced patch. + +commit 89a67a04e581423cdc443f2597cb1e2c7d8cc50f +Author: dtucker@openbsd.org +Date: Fri Dec 5 08:09:34 2025 +0000 + + upstream: Shell compatibility fix. + + OpenBSD-Regress-ID: bceaeb267d49c13e4a797c42e93b8f0cdb14dbd7 + +commit f4e79a4ba91cf0fd7397846424d1b261f3648708 +Author: djm@openbsd.org +Date: Fri Dec 5 07:43:24 2025 +0000 + + upstream: unit tests for convtime_double() + + OpenBSD-Regress-ID: d3ba7b894019b4128845d638c78fca37b3b6eecf + +commit c48de35bea389308428cb47b5ee55b1b1fb4567c +Author: djm@openbsd.org +Date: Fri Dec 5 07:49:45 2025 +0000 + + upstream: convert PerSourcePenalties to using floating point time, + + allowing penalties to be less than a second. This is useful if you need to + penalise things you expect to occur at >=1 QPS. + + feedback dtucker / deraadt; ok deraadt@ + + OpenBSD-Commit-ID: 89198be755722131b45a52d22d548e4c602201f0 + +commit f45cd249e45a15c84bf1316ac719039d04a74e84 +Author: djm@openbsd.org +Date: Fri Dec 5 07:43:12 2025 +0000 + + upstream: Add convtime_double() that converts a string interval, + + such as "3w2d4h5m10.5s", into a floating point number of seconds. + + Reimplement the existing convtime() function using convtime_double() + (it just drops the fractional seconds) + + lots of feedback deraadt@ / dtucker@; ok deraadt@ + + OpenBSD-Commit-ID: 053cdd0c72325a20efc6613caa847473fb89e36f + +commit b7dc1d95ee838c86a93df59663dad32e9b555520 +Author: dtucker@openbsd.org +Date: Fri Dec 5 06:55:22 2025 +0000 + + upstream: Add test for ssh -Oconninfo mux command. + + OpenBSD-Regress-ID: e939edc41caad8b6ad00ff294f33b61ed32a1edd + +commit eb97fc2b5e7c85a37fdb3f8a6ee1d665ef086c3f +Author: dtucker@openbsd.org +Date: Fri Dec 5 06:16:27 2025 +0000 + + upstream: Add an ssh -Oconninfo command + + that shows connection information, similar to the ~I escapechar. + This is the first use of the mux extension mechanism, so it should be + both forward and backward compatible: a new client talking to an old + server will not allow the "conninfo" request to be sent, but everything + else should work seamlessly. feedback and ok djm@ + + OpenBSD-Commit-ID: 50f047a85da277360558cabdfed59cb66f754341 + +commit 66622394fd3a51e9a6c99c39a068f8ba709542fa +Author: djm@openbsd.org +Date: Wed Dec 3 06:29:50 2025 +0000 + + upstream: correctly quote filenames in verbose output for local->local + + copies; from Colin Watson via bz3900; ok dtucker@ + + OpenBSD-Commit-ID: 5c09b030e2024651ebc8c1f9af6a8a2d37912150 + +commit 8fce5520a1c9c2cf3fc6c6974dd158f4b3ce9c4e +Author: dtucker@openbsd.org +Date: Sat Nov 29 06:49:56 2025 +0000 + + upstream: Add local hostname and pid to ~I escape connection info, + + only display peer information for TCP connections including source address + and port This provides enough information to uniquely identify a connection + on the host or network. + + OpenBSD-Commit-ID: aa18a4af2de41c298d1195d2566808585f8ce964 + +commit 2e8b5de4a79fb393482465531be1e347b81699f3 +Author: dtucker@openbsd.org +Date: Sat Nov 29 05:00:50 2025 +0000 + + upstream: Add compression stats to ~I connection info escape + + option. + + OpenBSD-Commit-ID: 83424b71fc226ea6b3dc8dda39f993475fdbd775 + +commit 52037ed910a9dcb669b9c9f612ccac711ac586f2 +Author: dtucker@openbsd.org +Date: Thu Nov 27 02:18:48 2025 +0000 + + upstream: Add Escape option ~I that shows information about the current + + SSH connection. ok djm@, "I like/want" sthen@ florian@ + + OpenBSD-Commit-ID: 0483fc0188ec899077e4bc8e1e353f7dfa9f5c1d + +commit 0fb1f3c9955d78fb0959842202b9ecfc36e37486 +Author: djm@openbsd.org +Date: Tue Nov 25 01:14:33 2025 +0000 + + upstream: move mention of default MaxStartups (which uses the + + form. + + GHPR568 from Santiago Vila + + OpenBSD-Commit-ID: 7e68771f3cad61ec67303607afb3b85639288b29 + +commit 2d0d26602f739b4a3ddde6c4dbc8f3ddab38ac0d +Author: djm@openbsd.org +Date: Tue Nov 25 01:08:35 2025 +0000 + + upstream: Support writing ED25519 keys in PKCS8 format. GHPR570 from + + Josh Brobst + + OpenBSD-Commit-ID: 4f36019a38074b2929335fbe9cb8d9801e3177af + +commit c23122c5ea7348b7b6daa2982e53c201a5354007 +Author: djm@openbsd.org +Date: Tue Nov 25 00:57:04 2025 +0000 + + upstream: avoid leak of fingerprint on error path; from Lidong Yan via + + GHPR611 + + OpenBSD-Commit-ID: 253f6f7d729d8636da23ac9925b60b494e85a810 + +commit 6157e1c41071fb0f5621868c38861934284268b1 +Author: djm@openbsd.org +Date: Tue Nov 25 00:52:00 2025 +0000 + + upstream: don't set the PerSourceNetBlockSize IPv6 mask if sscanf + + didn't decode it. From Mingjie Shen via GHPR598 + + OpenBSD-Commit-ID: c722014e735cbd87adb2fa968ce4c47b43cf98b0 + +commit 1fdc3c61194819c16063dc430eeb84b81bf42dcf +Author: djm@openbsd.org +Date: Mon Nov 24 23:56:58 2025 +0000 + + upstream: give ssh-agent more time to start in tests; requested in + + GHPR602 + + OpenBSD-Regress-ID: 7d771db2c1d4a422e83c3f632ba1e96f72a262b8 + +commit 5e7c3f33b2693b668ecfbac84b85f2c0c84410c2 +Author: djm@openbsd.org +Date: Mon Nov 24 23:54:15 2025 +0000 + + upstream: When testing PKCS11, explicitly allow the module path in + + ssh-agent. + + Allows testing of PKCS11 modules outside system directories. + + From Morgan Jones via GHPR602 + + OpenBSD-Regress-ID: 548d6e0362a8d9f7d1cc01444b697a00811ff488 + +commit 69965aefe3355488e0462291be13a233b8405091 +Author: djm@openbsd.org +Date: Mon Nov 24 23:43:10 2025 +0000 + + upstream: When loading FIDO2 resident keys, set the comment to the + + FIDO application string. This matches the behaviour of ssh-keygen -K + + From Arian van Putten via GHPR608 + + OpenBSD-Commit-ID: 3fda54b44ed6a8a6f94cd3e39e69c1e672095712 + +commit 2238c48dc90dc56af1d86b298d2cb25fa0c7ef14 +Author: tb@openbsd.org +Date: Sun Nov 23 07:04:18 2025 +0000 + + upstream: pkcs11_fetch_ecdsa_pubkey: use ASN1_STRING accessors + + In anticipation of davidben and beck making ASN1_STRING opaque in + OpenSSL 4 with the aim of enabling surgery to make the X509 data + structure less bad [1], we need to use dumb accessors to avoid build + breakage. Fortunately only in one spot. + + This is OpenSSL 1.1 API and available in all members of the fork family. + + ok beck djm + + [1]: https://github.com/openssl/openssl/issues/29117 + + OpenBSD-Commit-ID: 0bcaf691d20624ef43f3515c983cd5aa69547d4f + +commit 643222df689c95efff9e9506b76de458f69dd9c7 +Author: Darren Tucker +Date: Fri Nov 21 14:28:20 2025 +1100 + + Update OSSFuzz link to current bug tracker. + +commit 2efdfbb4d78b9bbb73f55af150e8f985d4fe4c0f +Author: Darren Tucker +Date: Fri Nov 21 14:21:07 2025 +1100 + + Add VM CI and CIFuzz status badges. + +commit 71e8779113965d60d91ba2d15cdeeb43ecf230a7 +Author: djm@openbsd.org +Date: Fri Nov 21 01:29:27 2025 +0000 + + upstream: unit tests for sshbuf_get_nulterminated_string() + + OpenBSD-Regress-ID: cb0af1e4d6dcc94e263942bc4dcf5f4466d1f086 + +commit dec6334aaf6f542f34a0aca27dc2f535e9161a67 +Author: djm@openbsd.org +Date: Fri Nov 21 01:29:06 2025 +0000 + + upstream: add a sshbuf_get_nulterminated_string() function to pull a + + \0- terminated string from a sshbuf. Intended to be used to improve parsing + of SOCKS headers for dynamic forwarding. + + ok deraadt; feedback Tim van der Molen + + OpenBSD-Commit-ID: cf93d6db4730f7518d5269c279e16b172b484b36 + +commit a8718c3fc52511e5237f1cbe10c210948c5616ea +Author: dtucker@openbsd.org +Date: Thu Nov 20 05:07:57 2025 +0000 + + upstream: Free opts in FAIL_TEST. It should always be NULL anyway so + + this is a no-op, but it should placate Coverity CID 405064. + + OpenBSD-Regress-ID: 06789754de0741f26432c668fad8b9881c14c153 + +commit d68d528fefeca1e331696296ef5db7c4db246f9a +Author: dtucker@openbsd.org +Date: Thu Nov 20 05:10:56 2025 +0000 + + upstream: Plug leaks while parsing Match blocks. Coverity CID + + 469304, ok djm@ + + OpenBSD-Commit-ID: f9b79b86879a953ad034e6b92a398265b251bea7 + +commit e3f1fbb427df898d70083b42caab72baaa715400 +Author: dtucker@openbsd.org +Date: Thu Nov 20 05:10:11 2025 +0000 + + upstream: Plug leaks while parsing Match blocks. Coverity CID + + 515634, ok miod@ djm@ + + OpenBSD-Commit-ID: c7932eddecd47e5122e945246a40c56ffa42a546 + +commit ccad76e9e1e4f06889ee023893cea98bc165858b +Author: Darren Tucker +Date: Tue Nov 18 20:14:44 2025 +1100 + + Pull in rev 1.17 for spelling fix. + + Prompted by github PR#609 from Edge-Seven. + +commit 58533bbdf7aa0548de8e2abd3cb2de0593fa9fdc +Author: jca@openbsd.org +Date: Mon Nov 17 12:59:29 2025 +0000 + + upstream: Export XDG_RUNTIME_DIR to child ssh sessions + + Currently setusercontext(LOGIN_SETALL) does create the directory in + /tmp/run/user, since LOGIN_SETXDGENV is part of LOGIN_SETALL, but the + env variable wasn't exported. + + ok djm@ + + OpenBSD-Commit-ID: 02b8433f72759b3a07b55cbc5a7cdb84391b0017 + +commit e4cc5ab0efd85f01c0e1ae46825ffc0c7a8f44ce +Author: djm@openbsd.org +Date: Mon Nov 17 05:24:42 2025 +0000 + + upstream: don't strnvis() log messages that are going to be logged + + by sshd-auth via its parent sshd-session process, as the parent will also run + them though strnvis(). + + Prevents double-escaping of non-printing characters in some log + messages. bz3896 ok dtucker@ + + OpenBSD-Commit-ID: d78faad96a98af5269d66ddceee553cf7d396dfe + +commit bad220decb95d3b5cc6e30f843c4fc9d9b0b7a67 +Author: Darren Tucker +Date: Mon Nov 17 21:36:45 2025 +1100 + + Remove obsolete CVSID. + +commit 2fe6e406b496b54351dab923f9be95579d39d071 +Author: dtucker@openbsd.org +Date: Mon Nov 17 09:59:13 2025 +0000 + + upstream: Ensure both sides of the test are non-NULL instead of just + + either. Coverity CID 443285. + + OpenBSD-Regress-ID: aa90e57b1bc8efce9e50734a07a8ffec0680059a + +commit e2b93e16232834c61c9dcff5b20e4c55a26b324d +Author: Darren Tucker +Date: Thu Nov 13 23:30:48 2025 +1100 + + Move libcrypto init check into entropy.c. + + This prevents link errors with the openbsd-compat tests when the linker + tries to bring in all the logging bits. + +commit ec41739bd68d639b0847b366697706e7dab3498d +Author: Icenowy Zheng +Date: Fri Nov 7 14:27:35 2025 +0800 + + seccomp sandbox: allow uname(3) + + The uname(3) syscall is utilized by zlib-ng on RISC-V to decide whether + the kernel handles VILL bit of V extension properly (by checking the + kernel version against 6.5). + + Allow it in the seccomp sandbox. + + Signed-off-by: Icenowy Zheng + +commit 90501bc30ca94fa5443e2b7e2072d5d454587ef8 +Author: Darren Tucker +Date: Thu Nov 13 22:04:19 2025 +1100 + + Remove remaining OpenSSL_add_all_algorithms() calls. + + We already have OPENSSL_init_crypto() in the compat layer (now with a + check of its return code, prompted by tb@). Prompted by github PR#606 + from Dimitri John Ledkov. ok beck@ + +commit d9955e4571ec356ba4f2e99d01f7fa88f6e20a63 +Author: dtucker@openbsd.org +Date: Thu Nov 13 10:35:14 2025 +0000 + + upstream: Remove calls to OpenSSL_add_all_algorithms() + + and ERR_load_crypto_strings(). These are no-ops in LibreSSL, and in + Portable have been mostly replaced by a call to OPENSSL_init_crypto() + in the compat layer. ok tb@ + + OpenBSD-Commit-ID: 4c3e0af10fe276766054eda34428a37a5606d3ea + +commit 6aba7008e6451ae3f9298214b13b8eded5fd9ff0 +Author: djm@openbsd.org +Date: Thu Nov 13 05:13:06 2025 +0000 + + upstream: sync support for systems that lack __builtin_popcount() from + + portable + + unused on OpenBSD (nothing sets MISSING_BUILTIN_POPCOUNT), but it + makes syncing much easier. + + OpenBSD-Commit-ID: 496446300d82615b24f83eca886b8fabdbee445b + +commit 84347d67ad2d5ee0db43f32bca91bacccecdb647 +Author: djm@openbsd.org +Date: Thu Nov 13 04:56:23 2025 +0000 + + upstream: update our ML-KEM implementation to upstream libcrux + + v0.0.4 + + tested/ok tb@ + + OpenBSD-Commit-ID: 525a62549efbf53492adcb2c57e4872cdbaeed62 + +commit c09eeba78ad622b988ab7f8d96e75b7edd434598 +Author: tb@openbsd.org +Date: Fri Nov 7 06:29:45 2025 +0000 + + upstream: sshkey_ec_validate_public: zap trailing blank I missed on + + review + + OpenBSD-Commit-ID: b296bd6056f33fd567ca0d5e9123dac1ec00f037 + +commit 7cb3ea4dcc7d73b2fad6782a119901cfa2b022aa +Author: Darren Tucker +Date: Thu Nov 13 10:23:45 2025 +1100 + + Simplify git command to avoid yaml syntax error. + +commit 08786bbe7eebff316efb0b4ccb882f93f33a16b8 +Author: Darren Tucker +Date: Thu Nov 13 09:53:17 2025 +1100 + + Don't use OpenSSL's ed25519 if built without EC. + + Explicitly check for OPENSSL_NO_EC, since otherwise the test will link + but then fail at runtime. + +commit d12813314452173b1709f7fdbae74add84c0056f +Author: Damien Miller +Date: Fri Nov 7 15:49:55 2025 +1100 + + octal-escape the colon character + + Apparently these are YAML magic when followed by whitespace + +commit 5a104d81a2a916a6b9a42e28a7fa11bb781dfdf4 +Author: Damien Miller +Date: Fri Nov 7 15:44:18 2025 +1100 + + try single quotes instead of escaped quotes + +commit 48d8293956b9801b870a56782e19f29793ca04ba +Author: Damien Miller +Date: Fri Nov 7 15:42:57 2025 +1100 + + escape quotes in yaml + +commit 1f1d63e16b5ce67f6f2f1170ec7221f1e6bff530 +Author: djm@openbsd.org +Date: Fri Nov 7 04:33:52 2025 +0000 + + upstream: Escape SSH_AUTH_SOCK paths that are sent to the shell as + + setenv commands. + + Unbreaks ssh-agent for home directory paths that contain whitespace. + + Based on fix from Beat Bolli via bz3884; feedback/ok dtucker@ + + OpenBSD-Commit-ID: aaf06594e299940df8b4c4b9f0a1d14bef427e02 + +commit 5794f2a186ee8ea7db0002bf7470b817572aaef0 +Author: djm@openbsd.org +Date: Thu Nov 6 17:24:28 2025 +0000 + + upstream: sk-dummy.so needs sshlog() stub after ed25519-openssl.c + + change + + OpenBSD-Regress-ID: 50b7f49021b8085728d0544275e141fb1bf4a2b5 + +commit a1c526f29b47147046f77a0f74097008256396f6 +Author: djm@openbsd.org +Date: Thu Nov 6 01:33:26 2025 +0000 + + upstream: unit test for stringlist_append() and stringlist_free() + + OpenBSD-Regress-ID: a3a4dae538c831b3810f69abc34ad8504dc3c460 + +commit 9d8c686981834bc1dde09f5067ff925d8fc158f5 +Author: djm@openbsd.org +Date: Thu Nov 6 01:33:03 2025 +0000 + + upstream: link against ed25519-openssl.c instead of ed25519.c + + OpenBSD-Regress-ID: f789d46e99d2598929e3c2d00b45c47cc3102501 + +commit e57ef43c3ecb69aa237e2d88b793f18ee8a25817 +Author: anton@openbsd.org +Date: Sat Nov 1 05:39:25 2025 +0000 + + upstream: Cope with recent changes and don't link hash.c. + + OpenBSD-Regress-ID: 577ef2f36ee592528448e8c0f33499e2e3512054 + +commit 9bea081888fa659b964e6bfa41caca2b5def98c2 +Author: djm@openbsd.org +Date: Fri Nov 7 04:11:59 2025 +0000 + + upstream: Remove some unnecessary checks in + + sshkey_ec_validate_public() + MIME-Version: 1.0 + Content-Type: text/plain; charset=UTF-8 + Content-Transfer-Encoding: 8bit + + Checking nQ == infinity is not needed for cofactor 1 curves. + Checking x and y coordinates against order is not needed either. + + patch from Szilárd Pfeiffer, with further refinement by tb@ + ok tb@ + + OpenBSD-Commit-ID: ef985e2be7c64e215d064757d3fc65eb181e8ede + +commit 1399419f0b2d024bde968ffe769a3808611917e4 +Author: djm@openbsd.org +Date: Thu Nov 6 01:31:11 2025 +0000 + + upstream: move stringlist_append() and stringlist_free() to misc.c + + OpenBSD-Commit-ID: 7d047bbff6964b9abbc04e9b3e2e1b4cc1db0aea + +commit f2ff1d9c1687be313dd491fcd136c682ef51bea8 +Author: djm@openbsd.org +Date: Fri Oct 31 01:50:43 2025 +0000 + + upstream: cleanup file descriptors across PKCS#11 client/helper + + execution; ok markus + + OpenBSD-Commit-ID: 993628a5b361e30aa48bbb4c07667a280f3f23ab + +commit 7e5d404cf73b6762715eec69b67cce2c4801f9e9 +Author: Darren Tucker +Date: Sat Nov 1 08:34:15 2025 +1100 + + Support using git for OpenBSD src tree tests. + +commit d87e7f0bed66fc9f76fe4a2f43390fdc9a664132 +Author: Darren Tucker +Date: Sat Nov 1 08:33:07 2025 +1100 + + Add OpenBSD 7.8 test target. + +commit 2425d7faf4154b32b5f836596023cf2432b81eaf +Author: Damien Miller +Date: Fri Oct 31 13:47:49 2025 +1100 + + check PAM user against previous user, not pw_name + + Avoids early fatal() if the user doesn't exist. + + Reported by Viswesh Narayanan; ok dtucker@ + +commit 7e2f89b0fb72141abbce098e2682ba8e090cabfc +Author: Damien Miller +Date: Fri Oct 31 12:19:47 2025 +1100 + + skip pkcs11 tests when built --without-openssl + +commit 590a260f0bedc895688bb38b1cf6f0f72d8013e3 +Author: Damien Miller +Date: Fri Oct 31 12:19:34 2025 +1100 + + add sshlog() replacement to sk-dummy.so + +commit 57e347bae04cf214795fdeae3579991f0cc2e090 +Author: Damien Miller +Date: Fri Oct 31 11:16:29 2025 +1100 + + rename openbsd-compat sha2.h -> bsd-sha2.h + + avoids confusion with system header when included from files under + openbsd-compat/ + +commit a5f638585152863dc64ee9436a08e1d84735d740 +Author: Damien Miller +Date: Fri Oct 31 11:07:17 2025 +1100 + + fix linking for sk-dummy.so, used in tests + +commit c2a178959b03472c1b1677fea4bb263ed9fee2bd +Author: djm@openbsd.org +Date: Thu Oct 30 23:55:09 2025 +0000 + + upstream: don't link hash.c + + OpenBSD-Regress-ID: a145f09c1efb1fcd3924544463f1f94f5d4805c0 + +commit 249224a0d43fdd2a536d7476c2bb15f4006dbbdd +Author: miod@openbsd.org +Date: Thu Oct 23 19:06:10 2025 +0000 + + upstream: Prepare for gcc 3 leaving the building, COMPILER_VERSION + + can no longer get set to "gcc3". + + OpenBSD-Regress-ID: 02351ea947975b80be60b9a8c6e4dbb57789e890 + +commit 9dcd640d44b8270c75783ef662c340187250d6e4 +Author: dtucker@openbsd.org +Date: Thu Oct 23 06:15:26 2025 +0000 + + upstream: Check tmux version and skip if too old. ok djm@ + + OpenBSD-Regress-ID: fb62024eb753c61b4d78402ec8378af839fad26c + +commit 94a78254a1c953c2a55eb54f65a5d99873b54bdf +Author: djm@openbsd.org +Date: Thu Oct 30 23:19:33 2025 +0000 + + upstream: move crypto_hash_sha512() to be inline in crypto_api.h, saves + + about 0.5kb per binary and makes life easier for portable; with/ok dtucker@ + + OpenBSD-Commit-ID: 672d7390f78bb6581c12661d7f5adc8a9c6be564 + +commit 266647c5f2075d397bd5ed5316450183eda73388 +Author: djm@openbsd.org +Date: Thu Oct 30 20:49:10 2025 +0000 + + upstream: support ed25519 signatures via libcrypto. Mostly by Jeremy + + Allison Feedback tb@, ok tb@ markus@ + + OpenBSD-Commit-ID: e8edf8adffd5975d05769dde897df882d7933526 + +commit 4f3e65bda22b65dc5fff82df1e97af07456fed42 +Author: djm@openbsd.org +Date: Thu Oct 30 03:19:54 2025 +0000 + + upstream: Activate UnusedConnectionTimeout only after last channel + + has closed. Previously UnusedConnectionTimeout could fire early after a + ChannelTimeout. + + This was not a problem for the OpenSSH client because it terminates + once all channels have closed but could cause problems for other + clients (e.g. API clients) that do things differently. + + bz3827; ok dtucker + + OpenBSD-Commit-ID: ff2e4607cbd4e600de3c8a5ece3b0e4bb641ed8f + +commit e7f5928ef1c8e8c725bdca9cdd6b80e77fe774ac +Author: miod@openbsd.org +Date: Thu Oct 23 19:06:10 2025 +0000 + + upstream: Prepare for gcc 3 leaving the building, COMPILER_VERSION + + can no longer get set to "gcc3". + + OpenBSD-Commit-ID: 98eefed432ff8253b307002e20d28da14b93e7e3 + +commit 0ffb76c6590800958777cd0f7b1aaae19c74fa3f +Author: djm@openbsd.org +Date: Wed Oct 22 06:22:58 2025 +0000 + + upstream: more explicit synchronisation around killing tmux sessions + + between runs. + + OpenBSD-Regress-ID: 1735f5cb13ad281e869ab998c7d49b692ee3ed47 + +commit ffd086b69886e8cfeb74f9b2bcb18764bf7d9a52 +Author: djm@openbsd.org +Date: Wed Oct 22 05:22:31 2025 +0000 + + upstream: remove debugging junk + + OpenBSD-Regress-ID: 3247e0ac98ae4cfe4eede871ef424d166e29e828 + +commit 52712d5f11172ca98ffb0b2ac93007f74cb67134 +Author: djm@openbsd.org +Date: Tue Oct 21 23:30:01 2025 +0000 + + upstream: just skip the test if $PATH or $HOME has whitespace in it + + OpenBSD-Regress-ID: ccf75a29d1a300a35f63be0e4f11ad5276756275 + +commit a8eac05a85e31b11513a6a8dc5d662b14cbc2f4b +Author: djm@openbsd.org +Date: Tue Oct 21 22:13:27 2025 +0000 + + upstream: quote paths; avoids test failure when run from a path with a + + space in it + + OpenBSD-Regress-ID: e4b7bffc289f10d47c50c02dd70b0323078a83b4 + +commit 425e5b6bd765efbfc7691f43bfc08c86dc8a615e +Author: djm@openbsd.org +Date: Tue Oct 21 08:35:22 2025 +0000 + + upstream: fix test for executability of tmux + + OpenBSD-Regress-ID: a18119876ecfd95edb78225b086ac668eb0977ab + +commit d1d8144ea682adae5c3bb2994322fa524584ce8b +Author: djm@openbsd.org +Date: Tue Oct 21 08:34:52 2025 +0000 + + upstream: add some more synchronisation to avoid a race between + + command entry and ^C that showed up on the portable regress tests. + + OpenBSD-Regress-ID: 5527e74aed1b008aa7e5223ca5a84aedecd973d4 + +commit 8704c141bf6ded67ab466f5e987c49329ebbd968 +Author: dtucker@openbsd.org +Date: Tue Oct 21 07:18:27 2025 +0000 + + upstream: Always create logfiles. Should prevent "can't operate on + + symlink" warnings during test runs. + + OpenBSD-Regress-ID: 65cf5ce3c8b87b5609f1f3ea142b4f381128dc33 + +commit dc9af8fb0436013afb544248e0afc2fd02a1a8fa +Author: Mike Frysinger +Date: Sun Oct 19 09:33:23 2025 -0400 + + bsd-openpty: include stdio.h for snprintf + +commit afe83537e0c0c159c7c3b6ef859424f6da18169c +Author: Damien Miller +Date: Tue Oct 21 09:14:35 2025 +1100 + + include tmux in CI package list + +commit a750ec60782d21db69383344dda478342d40ffa1 +Author: Darren Tucker +Date: Mon Oct 20 18:31:08 2025 +1100 + + Detect tmux at configure time and pass to tests. + + ok djm@ + +commit 75faa8a167b5cd4453937387b15216aa3cbc52ce +Author: Darren Tucker +Date: Mon Oct 20 18:29:24 2025 +1100 + + Update LibreSSL versions and add 4.2.0. + +commit 74369b2b7c366887211ef5c092b0aaa60f31ef11 +Author: djm@openbsd.org +Date: Mon Oct 20 00:45:10 2025 +0000 + + upstream: regression test for "interactive" ssh with a PTY attached, + + using tmux + + would have likely caught the ControlPersist regression in 10.1. + + feedback nicm@ + + OpenBSD-Regress-ID: d4d709c08657769cb5691893cc98f34b6f537e76 + +commit a204650386124df8035b8c8613dccbe9b3158cdf +Author: Darren Tucker +Date: Fri Oct 17 16:26:22 2025 +1100 + + Retire macos-13 runners, add Intel-specific ones. + +commit a6503f1e22aa34ac08d5b4d2b6730954ffd30116 +Author: Darren Tucker +Date: Fri Oct 17 16:23:43 2025 +1100 + + If we have nfds_t, check if it's int or long. + + Should fix build on very old Mac OS X, eg 10.3. Spotted and patch tested + by Sevan Janiyan. + +commit ce49aceba9f4b5f34a1041145782914aa35ca880 +Author: Damien Miller +Date: Thu Oct 16 11:15:16 2025 +1100 + + link ssh against ssh-pkcs11.o + + Should fix PIN entry for direct use of PKCS11Provider in ssh(1) + bz3879 + +commit 946574b97ceae126e0f0af2db43abb454937defe +Author: djm@openbsd.org +Date: Thu Oct 16 00:01:54 2025 +0000 + + upstream: regress test for PKCS#11 directly in ssh (not via ssh-agent) + + would have caught bz3879 + + OpenBSD-Regress-ID: ceafb1e9a6c07185cc0cb0589f3170489a516123 + +commit e3fdb82fb02723dbe139f9d4be274d7fddfb7983 +Author: djm@openbsd.org +Date: Thu Oct 16 00:00:36 2025 +0000 + + upstream: missed a case in previous + + OpenBSD-Commit-ID: 271c5602b5e719ee3def19dbd9a33328b4fa7edc + +commit d926a84d17fb28bc94219e68575cb4847af02e9a +Author: djm@openbsd.org +Date: Wed Oct 15 23:55:01 2025 +0000 + + upstream: don't try to pledge() the client if a PKCS11Provider is + + in use + + OpenBSD-Commit-ID: 445b2bf4b1e36e515f4d888f35244fd2dcfbb566 + +commit 9c8572a357c071923569a62bd9cfb68b1f788e09 +Author: djm@openbsd.org +Date: Wed Oct 15 23:54:20 2025 +0000 + + upstream: mention this is for both ssh-pkcs11.c and + + ssh-pkcs11-client.c + + OpenBSD-Commit-ID: 26eff4b9a328fa056e98b997cb57254639e48fda + +commit a4e404a64b117a15453075ee26eb061d416e58cd +Author: Arnout Engelen +Date: Sat Jun 21 09:47:28 2025 +0200 + + mdoc2man: process `Dl` macros + + `Dl` marks a single line as 'literal'. Since we don't output single + lines differently in literal vs regular mode (we only insert line + breaks for multi-line blocks in literal mode), we can just skip it. + +commit 45e2d8861bb724cfced1bf0693a6418a0cba6ab2 +Author: Arnout Engelen +Date: Fri Jun 20 21:36:44 2025 +0200 + + mdoc2man: support `Ns` inside `Ic` + + When encountering an `Ns` mdoc macro ('no space') inside an `Ic` block + ('command'), such as for 'lines=number' in ssh-keygen.1, `mdoc2man` + just output the macro instead of processing it. + + This adds processing for `Ns` when seen inside an `Ic` block. + +commit 2b1761dea36c120417d8b73db8310dc09a781e6f +Author: Mike Frysinger +Date: Mon Oct 13 11:29:36 2025 -0400 + + gitignore: ignore all *~ files + + This is a common backup style. + +commit 3ccdd9841f48e7d660f8b60c996965e9dde0a3a9 +Author: Mike Frysinger +Date: Mon Oct 13 12:49:24 2025 -0400 + + bsd-misc: include sys/ioctl.h + + This file uses ioctl() to implement some fallback functions, but + doesn't include sys/ioctl.h for it. + +commit 3adc47e161901001816045c032fa61e94b0c9426 +Author: Damien Miller +Date: Tue Oct 14 14:52:50 2025 +1100 + + don't leak PAM handle on repeat invocations + + Reported by Casper Dik via bz3882; ok dtucker@ + +commit a6ee0eb8cd951d0a00b2f06687c77f8f573b5985 +Author: Darren Tucker +Date: Mon Oct 13 19:02:45 2025 +1100 + + Switch OpenBSD VMs to use doas instead of sudo. + + OpenBSD 7.3 packages have been removed from the mirrors so we can't + install sudo for it any more, so switch to the native doas utility. + +commit da2f945f62e5a462381103803ee72e924bd1f137 +Author: Damien Miller +Date: Mon Oct 13 14:33:04 2025 +1100 + + check whether diff accepts -N + +commit cd8c96f283dbad90991edc09ade962bcfd96adc9 +Author: djm@openbsd.org +Date: Mon Oct 13 00:56:15 2025 +0000 + + upstream: test remote/remote recursive transfers where the source + + path ends in ".." + + OpenBSD-Regress-ID: 2f42078cfcee986d08b5d135968b8de6186c0003 + +commit be0777ae3ef6d9deacb0e3c494674c84feac34bd +Author: djm@openbsd.org +Date: Mon Oct 13 00:55:45 2025 +0000 + + upstream: test recursive transfers, including cases where the + + source path ends in ".." + + OpenBSD-Regress-ID: a38e3dbc86f6b7a95605784dcc601f17ede9c3f0 + +commit 36a98fccaacbbf07eaf67855a8057cba724c5e91 +Author: djm@openbsd.org +Date: Mon Oct 13 00:55:09 2025 +0000 + + upstream: test implicit destination path selection when source path + + ends with ".." + + OpenBSD-Regress-ID: 42a88e7cdceee8a83879f5730199084ee4a95902 + +commit 4f14ca8633a2c8c0a1a19165663421f0ab32f6ab +Author: djm@openbsd.org +Date: Mon Oct 13 00:54:29 2025 +0000 + + upstream: similar to scp, fix implicit destination path selection + + when source path ends with ".."; ok deraadt@ + + OpenBSD-Commit-ID: 9b8d2a662d96b241293a88b3ea21f2419bfc4812 + +commit 6432b9f6a216d0f5fb43df500e9bc30bebb3f58b +Author: djm@openbsd.org +Date: Mon Oct 13 00:53:51 2025 +0000 + + upstream: when using the SFTP protocol for transfers, fix implicit + + destination path selection when source path ends with ".."; ok deraadt@ + bz3871 + + OpenBSD-Commit-ID: d75b3b006386c5302ed4f67c4add18464ab36a0b + +commit 30c20c901d8f665fb28edd006f6f8c1e46413051 +Author: dtucker@openbsd.org +Date: Sat Oct 11 23:39:14 2025 +0000 + + upstream: Import regenerate moduli. + + OpenBSD-Commit-ID: 8512e01cf917dca6455be561d66db8eeb49f3f0b + +commit b6fd0e6d085ef519982c968b57fbaa9e509e1a3a +Author: Damien Miller +Date: Fri Oct 10 15:23:59 2025 +1100 + + depend + +commit d6212b0b89241e96d2fea9619b2d66ea668bceaa +Author: djm@openbsd.org +Date: Fri Oct 10 00:31:53 2025 +0000 + + upstream: clean up more thoroughly between tests + + OpenBSD-Regress-ID: c8394eae7547374a8fc43d03d865539e2917ea50 + +commit 9525aa3ecc6b27643fb83d8be4d61e831e357134 +Author: djm@openbsd.org +Date: Thu Oct 9 23:58:27 2025 +0000 + + upstream: simplify + + OpenBSD-Regress-ID: 8e91a2a5c1eb50128de3be72118b544d73a86673 + +commit e7b4b3f153713c15e3888aa50df039b2445492dd +Author: djm@openbsd.org +Date: Thu Oct 9 23:26:47 2025 +0000 + + upstream: don't abuse SSHKEY_FLAG_EXT to signal that a key is in + + the agent, as that triggers special handling on sshkey_free() + + OpenBSD-Commit-ID: 2ae2247babd2db167a30cf7a4f7eae4f26c000a8 + +commit 59a336cfd1283f512f067e01bc91bda5af253f80 +Author: djm@openbsd.org +Date: Thu Oct 9 23:25:23 2025 +0000 + + upstream: downgrade a useless error() -> debug() + + OpenBSD-Commit-ID: 5b0c9bcddb324f8bed2c8e8ffe9c92d263adc2d9 + +commit 649c9994e7d1995a03d8621f1412cfee90a430af +Author: djm@openbsd.org +Date: Thu Oct 9 03:23:33 2025 +0000 + + upstream: silence "mm_log_handler: write: Broken pipe" logspam + + OpenBSD-Commit-ID: bcf7c6ea509e755bd5a7cd567ff7cad725111a14 + +commit fb0bf236b0237aa83a0c5b666af7bdc0423ac457 +Author: Darren Tucker +Date: Thu Oct 9 17:57:17 2025 +1100 + + Add tracking for 10.2 branch. + +commit 081b8dbbe90d81a43b5e0f1995fe59a0e319aa15 +Author: Damien Miller +Date: Thu Oct 9 13:12:15 2025 +1100 + + complete PKCS#11 stubs and move to ssh-pkcs11.c + + Should unbreak --disable-pkcs11 builds + +commit ac4457787900c99ada9cc3768249291b002fa16e +Author: Damien Miller +Date: Thu Oct 9 13:10:27 2025 +1100 + + some fixes to p11_setup + + 1. Use the ssh-keygen under test and not the one in $PATH + 2. Include a test PKCS#11 operation to ensure that the P11 stack is + working correctly. + + Previously, it was possible for p11_setup to return success on + configurations with PKCS#11 support disabled. + +commit 3470f465c6f5c7c371e73927ebb403dd7ba05893 +Author: Damien Miller +Date: Thu Oct 9 10:07:40 2025 +1100 + + link ssh-keygen directly against ssh-pkcs11.c + + Matches what OpenBSD does and fixes ssh-keygen regression in + certifying keys using a CA key hosted via ssh-agent (bz3877) + +commit 0f3b8fd68a29766697d7a709bae8b0a61da6cff2 +Author: djm@openbsd.org +Date: Wed Oct 8 21:48:40 2025 +0000 + + upstream: When tab-completing a filename, ensure that the completed + + string does not end up mid-way through a multibyte character, as this will + cause a fatal() later on. + + based on GHPR#587 from @TaoistBrickscarrier; feedback tb@ kevlo@ + ok dtucker@ + + OpenBSD-Commit-ID: efb977164b4e20d61204a66201a7592ba8291362 + +commit 0118c30acaff308deb089fc25fe98ef59a149ca5 +Author: djm@openbsd.org +Date: Wed Oct 8 21:02:16 2025 +0000 + + upstream: fix crash at exit (visible via ssh-keygen -D) when + + multiple keys loaded. ok markus deraadt dtucker + + OpenBSD-Commit-ID: baa9763ec69d162108dafd962792ec5610ff45c9 + +commit 64ea9e95256203f30f98a6896f4721fd223106aa +Author: djm@openbsd.org +Date: Wed Oct 8 00:32:52 2025 +0000 + + upstream: openssh-10.2 + + The only change since 10.1 is the channels.c fix + + OpenBSD-Commit-ID: 5eebeb0db14c694efd4ee96b5f16112e3e5d5ba9 + +commit bcf7c05a473f92a35f4f3b561fd7a1e339e0a30f +Author: Darren Tucker +Date: Wed Oct 8 11:26:52 2025 +1100 + + Fix header name and move return outside of ifdef. + + Fixes from Mike Frysinger via Github PR#597. + +commit b937061fe4922caced7b91442b3233c0bd763492 +Author: Darren Tucker +Date: Tue Oct 7 21:10:33 2025 +1100 + + Check HAVE_MMAP too now that configure sets it. + +commit 8d57083c062f03098c9f767ec8d6278dc549a2f6 +Author: Darren Tucker +Date: Tue Oct 7 21:07:05 2025 +1100 + + Use calloc for sshkeys if mmap is not supported. + + Based on Github PR#597 from Mike Frysinger, any bugs added by me. + +commit c97b931bffa481c72ff4bfddd9d59a2110899289 +Author: Darren Tucker +Date: Tue Oct 7 20:25:07 2025 +1100 + + Add fcntl.h to includes. + + From FreeBSD via bz#3874: "This was previously included due to nested + includes in Heimdal's headers. Without this, the build fails with an + error due to redefining AT_FDCWD." + +commit 8aa13832315e52c4404c993a59c6139b44ac6114 +Author: Daan De Meyer +Date: Mon Mar 20 20:22:14 2023 +0100 + + Only set PAM_RHOST if the remote host is not "UNKNOWN" + + When using sshd's -i option with stdio that is not a AF_INET/AF_INET6 + socket, auth_get_canonical_hostname() returns "UNKNOWN" which is then + set as the value of PAM_RHOST, causing pam to try to do a reverse DNS + query of "UNKNOWN", which times out multiple times, causing a + substantial slowdown when logging in. + + To fix this, let's only set PAM_RHOST if the hostname is not "UNKNOWN". + +commit 0bd6649ea80ead0cd6404dbc25b64937421b556e +Author: Darren Tucker +Date: Tue Oct 7 20:10:56 2025 +1100 + + Don't copy native host keys for hostbased test. + + Some github runners (notably macos-14) seem to have host keys where + public and private do not match, so generate our own keys for testing + purposes. + +commit 33b63718d40ccc555b8c7a24331a3790b2efc6c5 +Author: Darren Tucker +Date: Tue Oct 7 20:10:07 2025 +1100 + + Add 10.1 branch to ci-status page. + +commit 52411f15353257e9ec883fc044b7a56b6fca242d +Author: Darren Tucker +Date: Tue Oct 7 20:04:40 2025 +1100 + + Add clock_gettime compat shim. + + This fixes the build on macOS prior to 10.12 Sierra, since it does not + have it. Found and tested by Sevan Janiyan. + +commit beae06f56e0d0a66ca535896149d5fb0b2e8a1b4 +Author: djm@openbsd.org +Date: Tue Oct 7 08:02:32 2025 +0000 + + upstream: don't reuse c->isatty for signalling that the remote channel + + has a tty attached as this causes side effects, e.g. in channel_handle_rfd(). + bz3872 + + ok markus@ + + OpenBSD-Commit-ID: 4cd8a9f641498ca6089442e59bad0fd3dcbe85f8 + +commit 476bab6259d5a6ea0402ec79bc47ed61e2c15e86 +Author: Damien Miller +Date: Mon Oct 6 12:52:25 2025 +1100 + + depend + +commit af956575eba6bf6b6d6bc817e1aa6ed73a365984 +Author: Damien Miller +Date: Mon Oct 6 12:51:13 2025 +1100 + + update versions + +commit 2fd0945913a30fbbe7c02503347961df03f28e66 +Author: Damien Miller +Date: Mon Oct 6 12:48:16 2025 +1100 + + sync ssh-copy-id to upstream version 527be673f4d + +commit 981bb32bc6062fa5d6f11de7ffb732967463bf57 +Author: djm@openbsd.org +Date: Mon Oct 6 01:45:22 2025 +0000 + + upstream: openssh-10.1 + + OpenBSD-Commit-ID: 2a232c2d2fc05a23519f69bc29e6d8c076b97d97 + +commit b9a640a1a0dccfb56be684cc7ade402f57cf7ebd +Author: dtucker@openbsd.org +Date: Fri Oct 3 01:03:45 2025 +0000 + + upstream: If write() returned short, the subsequent write would restart + + from the beginning of the buffer not the end of what was written. Fix, since + we want modpipe to corrupt data for testing purposes deliberately not + accidentally. ok djm@ + + OpenBSD-Regress-ID: 50ca74d287445c58944f070bb92dc13b1d054b43 + +commit a0e5446ac85aca5a3ef9844eeedf787300fdb8b3 +Author: naddy@openbsd.org +Date: Sat Oct 4 21:41:35 2025 +0000 + + upstream: typos: a ssh* -> an ssh* + + ok dtucker@ + + OpenBSD-Commit-ID: a70fd2e1b23089260e8f5a7921b0debc06b011cb + +commit ade92f53c3bd4ad7dcd95334a194add57ec9ff71 +Author: djm@openbsd.org +Date: Fri Oct 3 00:09:26 2025 +0000 + + upstream: stray newline + + OpenBSD-Commit-ID: b47ed4fa93b781c7ec8ae2936526a290f4e17e1f + +commit a9cbe10da2be5be76755af0cea029db0f9c1f263 +Author: djm@openbsd.org +Date: Fri Oct 3 00:08:02 2025 +0000 + + upstream: include openssl/bn.h explicitly in files where we use BN_* + + makes things simpler for portable; from Mike Frysinger + + OpenBSD-Commit-ID: 717e93403fd1108e175afd7451b5a4ab46a598fe + +commit 3957cc2914cdc88932c972413853f8b68c1ffba5 +Author: dtucker@openbsd.org +Date: Thu Oct 2 08:38:43 2025 +0000 + + upstream: Relax array check slightly. Prevents compiler warnings + + in -portable when there are no kbdint devices present. ok djm@ + + OpenBSD-Commit-ID: c1c050cecd642d6073c792201908fd225191df93 + +commit 6a239b057be2897d7a597daaf5394f2e7312dc65 +Author: djm@openbsd.org +Date: Thu Oct 2 04:23:11 2025 +0000 + + upstream: backout r1.243 (fix for fatal during tab-completion with + + some multibyte sequences) as it breaks the common case for tab completion. + + Will deal with it properly after release. + + OpenBSD-Commit-ID: 196d00f5ff19579214de45357f16a1fb2d624be1 + +commit b9f6a84ea383d811216de38219472214963c10b2 +Author: Darren Tucker +Date: Thu Oct 2 10:48:04 2025 +1000 + + Pass COMPATINCLUDES down to openbsd-compat too. + + Fixes build on Solaris, AIX and probably others. + +commit 047e0221eaf9815775e8ea78c6d6add5ab0f68c7 +Author: Darren Tucker +Date: Wed Oct 1 14:34:02 2025 +1000 + + Pass new "compat includes" path via AC_SUBST. + + This fixes the build when the directory path containing a space. + Found by Sevan Janiyan, tested by Job Snijders. This doesn't fix + "make tests", however that is a different, pre-existing problem + that needs to be addressed separately. + +commit 5c50ddbe4deac83995edc1d014e9ba0d5efa18a6 +Author: Darren Tucker +Date: Wed Oct 1 13:37:35 2025 +1000 + + Remove compat "include" dir during distclean. + +commit aceabd62ce5833716dd2e99d4be4fcb603d263cc +Author: dtucker@openbsd.org +Date: Wed Oct 1 00:33:37 2025 +0000 + + upstream: Set keys to NULL after freeing in tests where the + + variables will be used again. Should prevent Coverity "potential use after + free" warnings. + + OpenBSD-Regress-ID: 24d141657d25977e41dfb0c58e9b74ab093972bf + +commit eb30a0d1493a97b5c14728846576dc6af5d442da +Author: dtucker@openbsd.org +Date: Wed Oct 1 00:30:19 2025 +0000 + + upstream: Get rid of utf8 droppings in commment since it confuses + + older shells. From Sevan Janiyan via openssh-unix-dev. + + OpenBSD-Regress-ID: 67c11a5cff6ef23538c77e9b29d538e175e6cfe3 + +commit d478e250230e917eeb5032238df0b9af357404ee +Author: Darren Tucker +Date: Wed Oct 1 12:17:54 2025 +1000 + + Update OpenSSL & LibreSSL versions we test against. + +commit 2c504a74ed81d13c8198a89ed1040d0fc5f73129 +Author: djm@openbsd.org +Date: Tue Sep 30 00:10:42 2025 +0000 + + upstream: during sftp uploads, avoid a condition where a failed write + + could be ignored if a subsequent write succeeded. + + This is unlikely but technically possible because sftp servers are + allowed to reorder requests. + + Reported by Graziano Stefani, ok tb@ + + OpenBSD-Commit-ID: 03904bce2c7f787223d01d7e1179fde15753eca3 + +commit 1f7556753869654ba5e2bf61e384c5da2db5ca6a +Author: djm@openbsd.org +Date: Tue Sep 30 00:06:06 2025 +0000 + + upstream: avoid a fatal() when sftp tab-completes filenames that + + share common utf-8 characters that don't encode to a complete codepoint + + from menthu.zhou via GHPR#587; ok dtucker@ + + OpenBSD-Commit-ID: e07e4d8a8cac032ab536570b8214e6ef6839b585 + +commit 42b14ff1e06fd683c7d15a6b2816c16108873a5a +Author: djm@openbsd.org +Date: Tue Sep 30 00:03:09 2025 +0000 + + upstream: fix memory leak in mux_client_request_stdio_fwd GHPR#575 + + by Boris Tonofa; ok dtucker + + OpenBSD-Commit-ID: 410cdd05242304bd0196b9172ce5fcaf89d2d8ce + +commit e5055ef26abcffd3f99669e411ea6b35ca166111 +Author: Allison Karlitskaya +Date: Wed Sep 3 20:07:55 2025 +0200 + + Don't log audit messages with UNKNOWN hostname + + The `host` parameter to audit_log_acct_message() is documented as + follows: + + host - The hostname if known. If not available pass a NULL. + + but we pass the string "UNKNOWN" in case we don't know the hostname. + Make sure we pass NULL instead. + + This avoids having the audit system attempt to perform a DNS lookup on + the hostname "UNKNOWN", which tends to result in long delays when + attempting to login. + +commit d343df4019b4369ce7f87e9bf6bbc80b81cd263d +Author: zhangjun +Date: Fri Aug 22 16:49:07 2025 +0800 + + ensure struct passwd fields are non-NULL in pwcopy + + Android libc can return NULL pw_gecos, for example. + +commit 893a579e4b37e6bd89d206dc8e7ac2a906ccf114 +Author: dtucker@openbsd.org +Date: Mon Sep 29 21:37:52 2025 +0000 + + upstream: Add explicit check for array overflow. + + The array is bounded by a NULL sentinel which already prevents this, + however since we check the bit vector for overflow Coverity assumes that + check is for the devices array and flags it as a potential overflow. + Adding this additional check on the array placates CID 896018. ok djm@ + deraadt@ + + OpenBSD-Commit-ID: e92fff41341b38e4206a70655cc9acaaa032ebee + +commit 90f49a185ac1a786d9f7e9a710b369afb3692a65 +Author: dtucker@openbsd.org +Date: Mon Sep 29 21:30:15 2025 +0000 + + upstream: Move ifdef to start of file. Removes diff vs portable. + + OpenBSD-Commit-ID: 55058ac3d477e4c696575039f5b275522b99ffea + +commit 2f71b44d48dc8da7fb743d6ffe609aea5a645edb +Author: dtucker@openbsd.org +Date: Mon Sep 29 21:29:22 2025 +0000 + + upstream: Include misc.h. Removes diff vs portable. + + OpenBSD-Commit-ID: 8aa48451fe5c37f04a339450c4ed9cfb8f4c288f + +commit dfb991bdd826517bbce1cf62ce07bcb3e48a2f27 +Author: dtucker@openbsd.org +Date: Mon Sep 29 21:28:33 2025 +0000 + + upstream: Sort headers as per KNF. Removes diff vs portable. + + OpenBSD-Commit-ID: 55f5b9eaeb826a25cfb506a78136094275a71bcb + +commit c82f4dd6b723a8365b4c538d7c99fe8e46985ed0 +Author: dtucker@openbsd.org +Date: Mon Sep 29 07:40:55 2025 +0000 + + upstream: Null out keys after freeing in tests in the case where we + + potentially reuse the variable. Fixes Coverity CID 405057. + + OpenBSD-Regress-ID: c52e86502b33bfa6e448448a74a0217dd519dd58 + +commit fda31e1e5179b4e70c27094ebb303ee47c11a5a7 +Author: djm@openbsd.org +Date: Mon Sep 29 03:17:54 2025 +0000 + + upstream: avoid spurious error message when loading certificates + + only bz3869 + + OpenBSD-Commit-ID: e7848fec50d15cc142fed946aa8f79abef3c5be7 + +commit bcd88ded2fff97652d4236405a3354ca66f90f7e +Author: djm@openbsd.org +Date: Mon Sep 29 02:32:15 2025 +0000 + + upstream: kbd-interactive device names should be matched against + + the full device name, not a prefix. Doesn't matter in practice as there is + only one kbd-int device supported (PAM xor BSD auth), and an attacker would + still need to successfully authenticate against an incorrectly-selected + device. + + reported by ashamedbit, NobleMathews; ok deraadt@ + + OpenBSD-Commit-ID: cf75d4f99405fbb41354c4ae724a3b39a3b58f82 + +commit b1c4bf5c2f1c2b30698dbaadc5d823862213f1fc +Author: jsg@openbsd.org +Date: Thu Sep 25 12:52:21 2025 +0000 + + upstream: avoid use-after-free in update_krl_from_file() found with + + clang scan-build, ok dtucker@ + + OpenBSD-Commit-ID: 8ec86eca573740c94d5bc7e252959174555f4eb8 + +commit b06a150bc903a0cf898406384d5a34059d0f2d8f +Author: Darren Tucker +Date: Sat Sep 27 20:20:34 2025 +1000 + + Stop testing OpenBSD ubsan until fixed upstream. + +commit 97b32fa2af25c16aec4de85c5cbb63fd038b4dfa +Author: dtucker@openbsd.org +Date: Fri Sep 26 04:40:45 2025 +0000 + + upstream: Use $OBJ for temp file in maxstartups idempotence test. + + Fixes test in -portable when run out-of-tree. + + OpenBSD-Regress-ID: 8578be08238af4abe2dc91af1c199f7f71f1a7a2 + +commit b4ceca952b85752958d849508294afdc56dfcb9f +Author: Darren Tucker +Date: Fri Sep 26 22:28:13 2025 +1000 + + Shorten workflow names to fit in a single line. + +commit 9824ec515ed6256c1a98d66049471053f965b75e +Author: Darren Tucker +Date: Fri Sep 26 22:26:33 2025 +1000 + + Update link to oss-fuzz bug tracker. + + Remove 9.8 branch. + +commit 37d996bd0537837f15fc540d5aebb1ef2faf2268 +Author: dtucker@openbsd.org +Date: Thu Sep 25 22:17:29 2025 +0000 + + upstream: Check return codes of sshbuf functions. + + Fixes Coverity CIDs 405059 and 405061. + + OpenBSD-Regress-ID: defa55d32892172251bbd5efd15731ce55888247 + +commit 6c3c9f03c3c2cc4e40decbb49b8486abfb9e57df +Author: Darren Tucker +Date: Fri Sep 26 08:23:21 2025 +1000 + + Replace hand-rolled modulo with arc4random_uniform. + + Fixes potential modulo-by-zero UB flagged by Coverity CID 405068 + +commit e914e61eb88e22e5b725c399698256c54589ca32 +Author: Darren Tucker +Date: Thu Sep 25 17:50:07 2025 +1000 + + Remove status bits from OpenSSL >=3 version check. + + OpenSSL traditionally did not guarantee ABI compatibility across release + (and development) versions. Because of this, OpenSSH checked the lower 4 + "status" bits returned by OpenSSL_version_num(), which were originally + set to 0 for development versions and 0xf for release versions and, if + they did not match, would report the discrepancy and exit. + + OpenSSL (unintentionally) changed these bits in the 3.0.0 and subsequent + 3.x releases, setting them to zero in the release versions (which happened + to also match the documentation), then changed them back in the 3.5.3 + release. If OpenSSL was upgraded to (or from) this version without + recompiling OpenSSH, it would cause OpenSSH flag it as potentially + incompatible and refuse to use it. Ultimately OpenSSL rolled this + back, but the check now has no value so is being removed for OpenSSL + versions >=3. + + bz#3865 and https://github.com/openssl/openssl/issues/28575, ok djm@ + +commit 35f3e2a41c2afe7a68a8a4efb3eb385e7f8d247d +Author: Darren Tucker +Date: Thu Sep 25 18:06:55 2025 +1000 + + Update pledge() interface to match current OpenBSD. + + ok djm@ + +commit 7ce3823547578a3b083085744c1fea39237197a2 +Author: Darren Tucker +Date: Tue Sep 23 22:12:19 2025 +1000 + + Merge all putty tests into a single test. + + The lets us reuse the built OpenSSH binaries and replaces 12*4min of + tests with a single 14min one. + +commit 1362f6c0f4ca3306a201a6572bb9ec0d47d8edb3 +Author: Darren Tucker +Date: Thu Sep 25 18:20:53 2025 +1000 + + Add #ifdefs in pwfree to match those in pwcopy. + + Fixes build on many platforms. + +commit 8235dc3d82c0ac347a3600df0907c6573720fbaa +Author: djm@openbsd.org +Date: Thu Sep 25 07:05:11 2025 +0000 + + upstream: fix some one-off leaks in ssh.c; ok dtucker@ + + OpenBSD-Commit-ID: bf3c27ffe4b3cccb6553b554ec4c04929065a2bc + +commit 846987d1233f24bbe87ebed347e328f45525388a +Author: djm@openbsd.org +Date: Thu Sep 25 07:04:38 2025 +0000 + + upstream: fix some one-off leaks in ssh-keygen; ok dtucker@ + + OpenBSD-Commit-ID: 32f51289c93246474659aa49067926fcab9e02e8 + +commit a1a7df8b3694fdd7b55ad6bb8fa7b3d5d7f5b89a +Author: djm@openbsd.org +Date: Thu Sep 25 07:00:43 2025 +0000 + + upstream: fix some leaks in ssh-add; feedback/ok dtucker@ + + OpenBSD-Commit-ID: 441302917de31a128c1d6d63acccc67042fcf349 + +commit a8a2702bcd9e81a086e6d2c278f1b62f9d8bf3a1 +Author: djm@openbsd.org +Date: Thu Sep 25 06:57:54 2025 +0000 + + upstream: fix some leaks; feedback/ok dtucker@ + + OpenBSD-Commit-ID: 05bdbc2e494b87a4a79e509020bd8249c86a4ff0 + +commit a071af0682d686de85cf471f5e04deaee4d90adb +Author: djm@openbsd.org +Date: Thu Sep 25 06:45:50 2025 +0000 + + upstream: wait for the unprivileged sshd-auth process to exit + + before closing the fd it uses to report log messages + + This avoids a race where the child process notices the + fd was closed before exiting and spams the logs. + + ok dtucker@ + + OpenBSD-Commit-ID: 7cddaa41be3b955e6bed570900db7ab8817b1e76 + +commit 4fddebe7f524b3403c876c3b399d5ce7ce3390a6 +Author: djm@openbsd.org +Date: Thu Sep 25 06:33:19 2025 +0000 + + upstream: add some functions to free various structs, including + + channels data and packet state; ok dtucker@ tb@ + + OpenBSD-Commit-ID: a8b3705309d632cdae370d4147a03e703087b0d1 + +commit d0c1e73d408a24b2db18c0aa1a0108bea0f24210 +Author: djm@openbsd.org +Date: Thu Sep 25 06:31:42 2025 +0000 + + upstream: fix leaks of config objects in + + mm_decode_activate_server_options ok dtucker@ tb@ + + OpenBSD-Commit-ID: 211f4d7d02e847bd1bcb460f6beb11658809a742 + +commit b62aa85dcbc8f03bf91d26d14fbf8fd5e172d882 +Author: djm@openbsd.org +Date: Thu Sep 25 06:25:38 2025 +0000 + + upstream: clarify intent and avoid (harmess, defined behaviour) + + unsigned underflow. ok tb@ + + OpenBSD-Commit-ID: b73bf5f1f381c3e4561a6cc706fb1cd77c939cd8 + +commit 6f28a935cc7d073e6647643e81d98b5831df204f +Author: jsg@openbsd.org +Date: Thu Sep 25 06:23:19 2025 +0000 + + upstream: consistently use NULL for null pointer constants found + + with sparse, ok djm@ + + OpenBSD-Commit-ID: 1067504b63732d809d0d57ad4bc626818d112772 + +commit 0af7e5b690e2cfe8824f04f154b0e543509dbefd +Author: jsg@openbsd.org +Date: Thu Sep 25 02:15:39 2025 +0000 + + upstream: remove unneeded externs ok djm@ + + OpenBSD-Commit-ID: fe553193e910a122505142a4e1db7358cc1ae653 + +commit ae62a16118bb96a8e449ef25f5e55ef86a52cefb +Author: jsg@openbsd.org +Date: Thu Sep 25 02:12:16 2025 +0000 + + upstream: remove prototype for removed ssh_packet_set_tos() ok + + djm@ + + OpenBSD-Commit-ID: 396f82995074ef4d7b9ce44168266ef4640d9985 + +commit d8588478850463f8945aa18d0358b2b227f8b57a +Author: jsg@openbsd.org +Date: Wed Sep 24 00:51:28 2025 +0000 + + upstream: spelling; ok dtucker@ + + OpenBSD-Commit-ID: 93870117b0153859dd8baa80b97e44d4558c786b + +commit eff358890a7cab1e7c2fec62e5b9914d2c1c8703 +Author: Darren Tucker +Date: Tue Sep 23 16:51:34 2025 +1000 + + Merge VM tests into a single workflow file. + + Should make it easier to manage, although it may cause a few extra runs. + +commit d00015d21190517a1f505eb8120f716b1c2e4055 +Author: Darren Tucker +Date: Tue Sep 23 16:38:45 2025 +1000 + + Test openssl-3.6 branch not beta1. + +commit 31fce4fc5aaf79b9a4bccf09467e86c56b482bde +Author: Darren Tucker +Date: Tue Sep 23 15:51:14 2025 +1000 + + Test openssl-3.6.0-beta1. + +commit b94e7251a17a497669e825cb70ac79c96bdc3472 +Author: Darren Tucker +Date: Tue Sep 23 11:32:57 2025 +1000 + + Specify rpath when building OpenSSL. + +commit 83853aa5e35f3da0690bccd2983764d4e749a670 +Author: Darren Tucker +Date: Mon Sep 22 15:26:17 2025 +1000 + + Factor out OpenSSL install and test more versions. + + Move OpenSSL installation into its own script with a "-a" option to + install the "next" version to test for ABI compatibility. + +commit 2c1d38f7ffc8b8ec244bfe17ec8a85b3d737dcab +Author: Darren Tucker +Date: Mon Sep 22 16:55:49 2025 +1000 + + Exclude generated openbsd-compat/include directory. + +commit 67b3ed101a18348b564507f55e3ed4b7e0d23ff9 +Author: Darren Tucker +Date: Sat Sep 20 15:07:36 2025 +1000 + + Add OpenSSL 3.x ABI cross-compatibility test. + +commit c682c9f45a10ee0dc37fd716cfccd42271f92ddc +Author: Darren Tucker +Date: Sat Sep 20 15:05:19 2025 +1000 + + Add tests for OpenSSL 3.4 and 3.5 versions. + +commit 1659d0ac095608b809fd3173d2c48b7b39d40b02 +Author: Darren Tucker +Date: Sat Sep 20 15:53:04 2025 +1000 + + Build OpenSSL with -j4 to speed it up. + +commit ca9ac1109e2c875ea33da6818c1841aa2181e962 +Author: Darren Tucker +Date: Sat Sep 20 15:16:30 2025 +1000 + + Rerun tests if run_tests.sh changes. + +commit bc328144f149af07139a0f2c1329018cd85b86b7 +Author: djm@openbsd.org +Date: Fri Sep 19 01:32:45 2025 +0000 + + upstream: log at level INFO when PerSourcePenalties actually blocks + + access to a source address range. Previously this was logged at level + VERBOSE, which hid enforcement actions under default config settings. + + ok dtucker, markus + + OpenBSD-Commit-ID: ea2b0d7c2253ff5205719d74b526cf2870df894d + +commit 80993390bed15bbd1c348f3352e55d0db01ca0fd +Author: Darren Tucker +Date: Wed Sep 17 17:41:41 2025 +1000 + + Whitespace. + +commit fc704057ce6b75637645a4b9c917565b3563e21b +Author: Darren Tucker +Date: Wed Sep 17 17:33:25 2025 +1000 + + Move Gihub VMs to their own status line. + +commit 2202e5f9008003044cac01ed70d83deec42ad4e0 +Author: Darren Tucker +Date: Tue Sep 16 23:00:14 2025 +1000 + + Use relative URLs for status + +commit 7c32e09ea3e5c7e1fa0b7e2d4ddc83f8beadafed +Author: Darren Tucker +Date: Mon Sep 15 17:21:15 2025 +1000 + + Add VM test targets via vmaction on Github. + +commit a4aa090a3d40dddb07d5ebebc501f6457541a501 +Author: djm@openbsd.org +Date: Mon Sep 15 03:00:22 2025 +0000 + + upstream: memory leaks in unit tests + + OpenBSD-Regress-ID: af11ac7b8034b99ca324af4dae1ef5cd7700b273 + +commit 6f5942454ad6756355f3b4983ab882cf15e44440 +Author: djm@openbsd.org +Date: Mon Sep 15 05:17:37 2025 +0000 + + upstream: fix leaks of struct sftp_conn in scp; ok dtucker@ + + OpenBSD-Commit-ID: 76bea50b5b87b750c3771bf80feb6067d994a9d2 + +commit 52f38c76fcb38dfe619d8caa3bb4bb782c785026 +Author: djm@openbsd.org +Date: Mon Sep 15 04:52:41 2025 +0000 + + upstream: leak of principals file lines; ok dtucker@ + + OpenBSD-Commit-ID: 918bf1b70e5a969059300f3c23d45911690d9015 + +commit b9464cee0fd084d89d91696a17b3621b4cf512bf +Author: djm@openbsd.org +Date: Mon Sep 15 04:52:12 2025 +0000 + + upstream: leak of authentication options at exit; ok dtucker@ + + OpenBSD-Commit-ID: ba559799c2ff9b10afc3abefb1797c0843a6ff24 + +commit 0bb37080c86674de7cdfb56c80add3cd316c68a8 +Author: djm@openbsd.org +Date: Mon Sep 15 04:51:35 2025 +0000 + + upstream: memleak of keys not used for authentication; ok + + dtucker@ + + OpenBSD-Commit-ID: ddfda79d243150fbd382d8f2cd75a90a072b3669 + +commit ee99f6e93e0ee90eedbd27ffb9b7f9fef7b98010 +Author: djm@openbsd.org +Date: Mon Sep 15 04:50:42 2025 +0000 + + upstream: memleak of certificate path; ok dtucker@ + + OpenBSD-Commit-ID: 90dc5390f2756ba339e2e6df54d4b8651d64c1e7 + +commit 42fc6b6f9fbf58293b070f4de377c7695c275a8a +Author: djm@openbsd.org +Date: Mon Sep 15 04:49:41 2025 +0000 + + upstream: memleak of hostkey when downgrading host cert->key; ok + + dtucker + + OpenBSD-Commit-ID: f6f1f38a8ec144fb615434f6877066cf4610b826 + +commit bc60bd55cbc1f8139c840668733b51475cbefd93 +Author: djm@openbsd.org +Date: Mon Sep 15 04:49:00 2025 +0000 + + upstream: memleak of editline history; ok dtucker@ + + OpenBSD-Commit-ID: a244c54eb074cf7fbe28f7ac4f03ace270f7a999 + +commit ee77ab9b2ca2d70daf8d4352f5daffa8036ece64 +Author: djm@openbsd.org +Date: Mon Sep 15 04:48:29 2025 +0000 + + upstream: memleak of rfwd callback context; ok dtucker@ + + OpenBSD-Commit-ID: 70b2aafeaace90703dd16a44a2a0b723d9155f33 + +commit 0088b3f0ab2c615ae95b9f374963abaa0ab837ec +Author: djm@openbsd.org +Date: Mon Sep 15 04:47:49 2025 +0000 + + upstream: memleaks of request packet and hostkeys blob; ok + + dtucker@ + + OpenBSD-Commit-ID: 313b13a8e36b4ca8e064ee56792e67e0670a386a + +commit d68451a25808c4eee74b898873cd4761f73651ed +Author: djm@openbsd.org +Date: Mon Sep 15 04:41:20 2025 +0000 + + upstream: memleak of KRL revoked certs struct; ok dtucker + + OpenBSD-Commit-ID: f319868e0b2de49c41c735e75b87c403f009f5f9 + +commit 67940cc2f329427d3acb64d4893faf4527e58d5c +Author: djm@openbsd.org +Date: Mon Sep 15 04:40:34 2025 +0000 + + upstream: memleak of kex->server_sig_algs; ok dtucker@ + + OpenBSD-Commit-ID: 41a3f64edd2c9b8addb2e445514ae25c24819e2c + +commit fae8e41741d23298c94a1ea3ef8704a1cc186cb5 +Author: djm@openbsd.org +Date: Mon Sep 15 04:39:58 2025 +0000 + + upstream: fix memleak of channel forwarding permissions; ok + + dtucker@ + + OpenBSD-Commit-ID: 069745547109bc8fcc09fab5b19c53599cae99fd + +commit 03872018c14ed943bc01a4e88be59195a742f106 +Author: djm@openbsd.org +Date: Mon Sep 15 04:39:15 2025 +0000 + + upstream: when merging auth options into the active set, don't + + leak the old struct sshauthopt; ok dtucker@ + + OpenBSD-Commit-ID: c6bfd7bc2932e37f811b3c53272c3b919d33e75b + +commit efed5da4ced88170cf474246eff771dd16c7092f +Author: djm@openbsd.org +Date: Mon Sep 15 04:38:00 2025 +0000 + + upstream: fix memleak when applying certificate options; ok + + dtucker + + OpenBSD-Commit-ID: 36c219dcc05f4df82a0f9c500bdf5dbfea925289 + +commit edc601707b583a2c900e49621e048c26574edd3a +Author: djm@openbsd.org +Date: Thu Sep 11 07:23:32 2025 +0000 + + upstream: disable ssh-add autoexpiry of certificates when testing + + expired certificates + + OpenBSD-Regress-ID: 64aadd23d37fd0b3a06498151f2cf83be7ac342c + +commit c60153e4878f3a6700af69adbdd1863003e78abf +Author: djm@openbsd.org +Date: Thu Sep 11 07:22:37 2025 +0000 + + upstream: correct getopt() string + + OpenBSD-Commit-ID: 05ef9581a3dab32ec93aa5b9c3349ed1e7da9ec8 + +commit 7a4738af45201c115a9e20f830f30ed38ce6be76 +Author: djm@openbsd.org +Date: Thu Sep 11 03:29:58 2025 +0000 + + upstream: need time.h for time(3) + + OpenBSD-Commit-ID: 530964039cccab679432b6c5b28d2b0aa9760b00 + +commit 0c719c6aabc061f02a907fc96c390d0449b49f26 +Author: djm@openbsd.org +Date: Thu Sep 11 02:54:42 2025 +0000 + + upstream: When adding certificates to an agent, set the expiry to + + the certificate expiry time plus a short (5 min) grace period. + + This will cause the agent to automtically remove certificates shortly + after they expire. + + A new ssh-add -N option disables this behaviour. + + Feedback/ok deraadt@ + + OpenBSD-Commit-ID: 92fed1bba1025069ad45deebb534be7530e181df + +commit e9dcccc3541b0ae1c43581ed26215d5cc82e4be0 +Author: jsg@openbsd.org +Date: Mon Sep 8 00:31:54 2025 +0000 + + upstream: remove unused 0-sized files; ok deraadt@ + + OpenBSD-Commit-ID: 7e8178786157e863f6ff63c5d55200d7b6b04f9e + +commit d16b1b484a024ee6b35094e7d9d55bf96b96253b +Author: dtucker@openbsd.org +Date: Fri Sep 5 10:34:35 2025 +0000 + + upstream: Tabs->spaces. Removes diff vs portable. + + OpenBSD-Commit-ID: 06598021a9f08188dab29ac956b2baa002a0ff85 + +commit 3d8ae7f235b96da604b08c44ae83420e367eeab4 +Author: Tim Rice +Date: Mon Sep 8 12:53:10 2025 -0700 + + modified: regress/rekey.sh + Fix for when building out of tree. + +commit 54abadd3f286efea0dbbdbfea8011d5e1e30c074 +Author: Darren Tucker +Date: Sun Sep 7 13:35:22 2025 +1000 + + Accept OpenSSL 4.0.0-dev versions. + + They seem to work, at least for now. + +commit 67a8bf4e4057597170bfa923fe2ce5bf90c43974 +Author: Maxim Khon +Date: Mon Aug 18 12:05:42 2025 +0000 + + Use SSH_TUN_COMPAT_AF on FreeBSD. + + Otherwise tun forwarding from other OSes fails as soon as the first IPv6 + message is sent by the other side (which is usually a Router Solicitation + ICMPv6 message which is sent as soon as the interface is up): all other + OS'es use SSH_TUN_COMPAT_AF or SSH_TUN_PREPEND_AF which effectively uses + OpenBSD AF_INET/AF_INET6 values. + +commit 3ca274e44cb2c2351376fc14e4c3e92ba4a8f87b +Author: Darren Tucker +Date: Fri Sep 5 21:32:30 2025 +1000 + + Check for nlist function. + + Check for nlist function presence before attenmpting to use it instead + of relying on the presence of the nlist.h header. Mac OS X, in particular + has the header, but only has the function in the 32bit libraries. + +commit ee32a36c62424f13907023595bfa8b23a528ced1 +Author: dtucker@openbsd.org +Date: Fri Sep 5 10:23:55 2025 +0000 + + upstream: Order includes as per KNF and add time.h. Removes diff + + vs portable. + + OpenBSD-Commit-ID: 38043f0bfa17c48ef6d1a744c2834b4405bc9311 + +commit 0ac179c9540e2b05b4c1194db69ce01306c253d3 +Author: dtucker@openbsd.org +Date: Fri Sep 5 10:17:21 2025 +0000 + + upstream: Order headers as per KNF. Removes diff vs portable. + + OpenBSD-Commit-ID: 4df519fd9fa13ce9653adf7a3d1076e20591d886 + +commit e80322284f3ee70b6b760a9f83179470d675e5ba +Author: dtucker@openbsd.org +Date: Fri Sep 5 10:01:35 2025 +0000 + + upstream: Order headers as per KNF. + + OpenBSD-Commit-ID: 7156b69b0364c68e181e0f6fa17c0f05c72e8670 + +commit bb8ac0515e68cab63db2d026eb60127185a3d2b8 +Author: Darren Tucker +Date: Fri Sep 5 20:39:16 2025 +1000 + + Resync header order with upstream. + +commit 024b694249482698b0c73d24da0eaec696fca8c8 +Author: Darren Tucker +Date: Fri Sep 5 20:37:04 2025 +1000 + + Resync header order with upstream. + +commit aed6a958bc108faab64bc2855d6ed93894cfc6ff +Author: Darren Tucker +Date: Fri Sep 5 20:30:20 2025 +1000 + + Sync includes with upstream. + +commit 22cfd2dd32f34f0cea218dd651f3aa9544b6e3b5 +Author: Darren Tucker +Date: Fri Sep 5 20:26:14 2025 +1000 + + Move ssh-pkcs11.h include to match upstream. + +commit b34c16bc4cac2962cc6a7517efbc4fed2c8a2d9a +Author: Darren Tucker +Date: Fri Sep 5 20:20:27 2025 +1000 + + Reorder includes to match upstream. + +commit 441a8fa9a0178704bce497bff92ca43fcf04bf7a +Author: dtucker@openbsd.org +Date: Fri Sep 5 09:58:08 2025 +0000 + + upstream: Order headers as per KNF. Removes diff vs portable. + + OpenBSD-Commit-ID: db72be57429418f6a4319bbe34c98fc103e11ce0 + +commit 19d6a7afb256c4afc571dbf56a013ef91cd9596f +Author: dtucker@openbsd.org +Date: Fri Sep 5 09:49:26 2025 +0000 + + upstream: Order headers as per KNF. Also removes diff vs + + -portable. + + OpenBSD-Commit-ID: 2061307dc938712e524bc9da48a52f545e43670e + +commit 932e9f200bd48b7568eb21ec456c67ec92d517e2 +Author: dtucker@openbsd.org +Date: Fri Sep 5 09:31:31 2025 +0000 + + upstream: Remove unused rmd160.h header. ripemd160 support was + + removed in 2017. + + OpenBSD-Commit-ID: 937fca21498b921adf6e04bac120f4a2e7975b3c + +commit f93de828b9b0f29bff51d38ea92d0759595ec30b +Author: Darren Tucker +Date: Fri Sep 5 20:07:16 2025 +1000 + + Create replacement nlist.h if needed. + + Remove #ifdef HAVE_NLIST_H wrapper. ok djm@ + +commit 6aac2beaa53467e83f6a137376b6dcf423ab6f6c +Author: Darren Tucker +Date: Fri Sep 5 19:55:20 2025 +1000 + + Create replacement endian.h if needed. + + Remove #ifdef HAVE_ENDIAN_H wrapper. ok djm@ + +commit a60721c894f0a2ce973876d0f55617e187e6fab1 +Author: Darren Tucker +Date: Fri Sep 5 19:52:48 2025 +1000 + + Add /* WITH_OPENSSL */ comments. + + Removes diffs vs upstream. + +commit c729a833298d9d55ffb22771cf1400dfdc640164 +Author: Darren Tucker +Date: Fri Sep 5 19:22:37 2025 +1000 + + Move sys/time.h include to match upstream. + +commit caa973dd06a7be43c29353b256c9a473f5ad9882 +Author: Darren Tucker +Date: Fri Sep 5 19:13:52 2025 +1000 + + Create replacement netgroup.h if needed. + + Remove #ifdef HAVE_NETGROUP_H wrapper. ok djm@ + +commit 7d30526b7df14d960a5de63d6af823ffdab86518 +Author: Darren Tucker +Date: Fri Sep 5 18:24:59 2025 +1000 + + Remove stray #endif left from previous. + +commit 4911f2600fdbb1959311bb1886bfe51f7dd4a74e +Author: Darren Tucker +Date: Fri Sep 5 18:08:51 2025 +1000 + + Create replacement libgen.h if needed. + + Remove #ifdef HAVE_LIBGEN_H wrapper. ok djm@ + +commit 65dcdb56f5daee519ec824ae17e64412d2492f90 +Author: Darren Tucker +Date: Fri Sep 5 18:05:15 2025 +1000 + + Create replacement sys/un.h if needed. + + Remove #ifdef HAVE_SYS_UN_H wrapper. ok djm@ + +commit 60334af5a908ac3b263d2ec696f9977e20b739cb +Author: Darren Tucker +Date: Fri Sep 5 18:03:55 2025 +1000 + + Reformat replacement header check one per line. + +commit cd9ba068e36b0f37374d2eba2d19dacc7ea9a167 +Author: Darren Tucker +Date: Fri Sep 5 17:55:33 2025 +1000 + + Create replacement time.h if needed. + + Remove #ifdef HAVE_TIME_H wrapper. ok djm@ + +commit ea586edbcbec7089f768ed682a79a399eaa1e5b1 +Author: Darren Tucker +Date: Fri Sep 5 17:50:18 2025 +1000 + + Create replacement sys/stat.h if needed. - OpenBSD-Commit-ID: 25c57f22764897242d942853f8cccc5e991ea058 + Remove #ifdef HAVE_SYS_STAT_H wrapper. ok djm@ -commit 1bc426f51b0a5cfdcfbd205218f0b6839ffe91e9 -Author: naddy@openbsd.org -Date: Mon Sep 9 14:41:21 2024 +0000 +commit 59b80707c6cf45230597a800e7d2ce6b00ce35b5 +Author: Darren Tucker +Date: Fri Sep 5 17:44:07 2025 +1000 - upstream: document the mlkem768x25519-sha256 key exchange algorithm + Create replacement sys/time.h if needed. - OpenBSD-Commit-ID: fa18dccdd9753dd287e62ecab189b3de45672521 + Remove #ifdef HAVE_SYS_TIME_H wrapper. ok djm@ -commit 0a2db61a5ffc64d2e2961c52964f933879952fc7 +commit 82fed5110fe09e9af258a8f5a2f92ffb397fff5b Author: Darren Tucker -Date: Tue Sep 10 21:11:14 2024 +1000 +Date: Fri Sep 5 17:31:15 2025 +1000 - Spell omnios test host correctly. + Create replacement ifaddrs.h if needed. + + Remove #ifdef HAVE_IFADDRS_H wrapper. ok djm@ -commit 059ed698a47c9af541a49cf754fd09f984ac5a21 +commit 53887d8ebc583b51e996cb2bdeb11e054d36343b Author: Darren Tucker -Date: Tue Sep 10 18:52:02 2024 +1000 +Date: Fri Sep 5 17:27:43 2025 +1000 - Add omnios test target. + Create replacement util.h if needed. + + Remove #ifdef HAVE_UTIL_H wrapper. ok djm@ -commit f4ff91575a448b19176ceaa8fd6843a25f39d572 +commit 5f09983d1e724097bd577097fb0f2c00c2436f21 Author: Darren Tucker -Date: Tue Sep 10 18:45:55 2024 +1000 +Date: Fri Sep 5 17:24:50 2025 +1000 - Wrap stdint.h in ifdef. + Create replacement paths.h if needed. + + Remove #ifdef HAVE_PATHS_H wrapper. ok djm@ -commit ff714f001d20a9c843ee1fd9d92a16d40567d264 +commit d45b17dc5a0598dda2b11dc89598203408d2d59c Author: Darren Tucker -Date: Mon Sep 9 19:31:54 2024 +1000 +Date: Fri Sep 5 17:17:52 2025 +1000 - Also test PAM on dfly64. + Create replacement poll.h if needed. + + Remove #ifdef HAVE_POLL_H wrapper. ok djm@ -commit 509b757c052ea969b3a41fc36818b44801caf1cf -Author: Damien Miller -Date: Mon Sep 9 21:50:14 2024 +1000 +commit 9b2c5a2db0650e394597839ef00d797f57568937 +Author: Darren Tucker +Date: Fri Sep 5 17:06:14 2025 +1000 - stubs for ML-KEM KEX functions + Fill in missing system header files. - used for C89 compilers + Create replacement header files inside openbsd-compat for common headers + that are missing on a given platform. Usually these are just empty, + but in some cases they'll include the equivalent file. This avoids + having to wrap those includes in '#ifdef HAVE_FOO_H' and reduces the + diff vs OpenBSD. + + If we create any such headers, add the path to includes. + + Initially just stdint.h, more to follow. + + ok djm@ -commit 273581210c99ce7275b8efdefbb9f89e1c22e341 -Author: Damien Miller -Date: Mon Sep 9 17:30:38 2024 +1000 +commit f64701ca25795548a61614d0b13391d6dfa7f38c +Author: djm@openbsd.org +Date: Thu Sep 4 03:04:44 2025 +0000 - declare defeat trying to detect C89 compilers + upstream: repair test after changes to percent expansion of usernames - I can't find a reliable way to detect the features the ML-KEM code - requires in configure. Give up for now and use VLA support (that we - can detect) as a proxy for "old compiler" and turn off ML-KEM if - it isn't supported. + on the commandline. + + Test more cases that should/shouldn't expand and lightly test + username validity checks. + + OpenBSD-Regress-ID: ad4c12c70bdf1f959abfebd1637ecff1b49a484c -commit e8a0f19b56dfa20f98ea9876d7171ec315fb338a -Author: Damien Miller -Date: Mon Sep 9 16:46:40 2024 +1000 +commit 45698669d49949868b1f3d13dfda1b7cb70060ad +Author: djm@openbsd.org +Date: Thu Sep 4 00:37:10 2025 +0000 - fix previous; check for C99 compound literals + upstream: unit tests for sshbuf_equals and sshbuf_dtourlb64; ok - The previous commit was incorrect (or at least insufficient), the - ML-KEM code is actually using compound literals, so test for them. + deraadt@ + + OpenBSD-Regress-ID: bab54e2d4caa813036a63ee67e92c93e6712a5b9 -commit 7c07bec1446978bebe0780ed822c8fedfb377ae8 -Author: Damien Miller -Date: Mon Sep 9 16:06:21 2024 +1000 +commit 4be445116f1b56f14254b98d8b132bb25777e160 +Author: djm@openbsd.org +Date: Thu Sep 4 00:34:17 2025 +0000 - test for compiler feature needed for ML-KEM + upstream: unit tests for a bunch of misc.c functions; ok deraadt@ - The ML-KEM implementation we uses need the compiler to support - C99-style named struct initialisers (e.g foo = {.bar = 1}). We - still support (barely) building OpenSSH with older compilers, so - add a configure test for this. + OpenBSD-Regress-ID: 886cf142605405e777ee77a96b48694dc2e9235d -commit d469d5f348772058789d35332d1ccb0b109c28ef +commit e3699ff47df336f57da2e78188d0057f8368af56 Author: djm@openbsd.org -Date: Mon Sep 9 03:13:39 2024 +0000 +Date: Thu Sep 4 00:32:31 2025 +0000 - upstream: test mlkem768x25519-sha256 + upstream: fix sshbuf_dtourlb64() to not choke on empty buffers; - OpenBSD-Regress-ID: 7baf6bc39ae55648db1a2bfdc55a624954847611 + previously it incorrectly returned an error in this situation; ok deraadt + + OpenBSD-Commit-ID: e62773d6e8cb95a19aab54f0af0edbcd47b345c0 -commit 62fb2b51bb7f6863c3ab697f397b2068da1c993f +commit 8e85ad33cfcc71e03594e53f2e19d8ce2e27dcc6 Author: djm@openbsd.org -Date: Mon Sep 9 02:39:57 2024 +0000 +Date: Thu Sep 4 00:31:49 2025 +0000 - upstream: pull post-quantum ML-KEM/x25519 key exchange out from + upstream: fix rtrim() function to not attempt to delete whitespace - compile-time flag now than an IANA codepoint has been assigned for the - algorithm. + inside a string, just at the end. ok deraadt@ - Add mlkem768x25519-sha256 in 2nd KexAlgorithms preference slot. + OpenBSD-Commit-ID: d44deaa43580cd88de978dd5509b14e905b67b84 + +commit 43b3bff47bb029f2299bacb6a36057981b39fdb0 +Author: djm@openbsd.org +Date: Thu Sep 4 00:30:06 2025 +0000 + + upstream: don't allow \0 characters in url-encoded strings. - ok markus@ + Suggested by David Leadbeater, ok deraadt@ - OpenBSD-Commit-ID: 9f50a0fae7d7ae8b27fcca11f8dc6f979207451a + OpenBSD-Commit-ID: c92196cef0f970ceabc1e8007a80b01e9b7cd49c -commit a8ad7a2952111c6ce32949a775df94286550af6b +commit 35d5917652106aede47621bb3f64044604164043 Author: djm@openbsd.org -Date: Fri Sep 6 02:30:44 2024 +0000 +Date: Thu Sep 4 00:29:09 2025 +0000 - upstream: make parsing user@host consistently look for the last '@' in + upstream: Improve rules for %-expansion of username. - the string rather than the first. This makes it possible to use usernames - that contain '@' characters. - MIME-Version: 1.0 - Content-Type: text/plain; charset=UTF-8 - Content-Transfer-Encoding: 8bit + Usernames passed on the commandline will no longer be subject to + % expansion. Some tools invoke ssh with connection information + (i.e. usernames and host names) supplied from untrusted sources. + These may contain % expansion sequences which could yield + unexpected results. - Prompted by Max Zettlmeißl; feedback/ok millert@ + Since openssh-9.6, all usernames have been subject to validity + checking. This change tightens the validity checks by refusing + usernames that include control characters (again, these can cause + surprises when supplied adversarially). - OpenBSD-Commit-ID: 0b16eec246cda15469ebdcf3b1e2479810e394c5 + This change also relaxes the validity checks in one small way: + usernames supplied via the configuration file as literals (i.e. + include no % expansion characters) are not subject to these + validity checks. This allows usernames that contain arbitrary + characters to be used, but only via configuration files. This + is done on the basis that ssh's configuration is trusted. + + Pointed out by David Leadbeater, ok deraadt@ + + OpenBSD-Commit-ID: e2f0c871fbe664aba30607321575e7c7fc798362 -commit 13cc78d016b67a74a67f1c97c7c348084cd9212c +commit f38a552dc71f20df2544338099e3fe2563f1a9ca +Author: Damien Miller +Date: Wed Sep 3 09:42:39 2025 +1000 + + missing header + +commit cc4eb3d6943cb57e08ab3abbcf92644deb429e46 Author: djm@openbsd.org -Date: Wed Sep 4 05:33:34 2024 +0000 +Date: Tue Sep 2 11:08:34 2025 +0000 - upstream: be more strict in parsing key type names. Only allow + upstream: simplify algorithm list functions using xextendf(); ok - shortnames (e.g "rsa") in user-interface code and require full SSH protocol - names (e.g. "ssh-rsa") everywhere else. + dtucker@ - Prompted by bz3725; ok markus@ + OpenBSD-Commit-ID: ffc5f8d0c25b95705a8a66c8b634f98d23bd92dc + +commit 8866d24cdd1d6e73bb3220b753f94e255c49ff96 +Author: djm@openbsd.org +Date: Tue Sep 2 11:04:58 2025 +0000 + + upstream: unit test for xextendf() - OpenBSD-Commit-ID: b3d8de9dac37992eab78adbf84fab2fe0d84b187 + OpenBSD-Regress-ID: ddb3b4db1a52dda23696b967470882fe2b9c3af7 -commit ef8472309a68e319018def6f8ea47aeb40d806f5 +commit 2f369d3fd0ff3715c2b32dff5cb35c0330272445 Author: djm@openbsd.org -Date: Wed Sep 4 05:11:33 2024 +0000 +Date: Tue Sep 2 09:41:23 2025 +0000 - upstream: fix RCSID in output + upstream: fix comment on sshbuf_froms() - it *returns* an error - OpenBSD-Commit-ID: 889ae07f2d2193ddc4351711919134664951dd76 + code, the allocated buffer is passed via argument + + OpenBSD-Commit-ID: b2b0a76df71328f39c3e2ad941a4d87085d8335d -commit ba2ef20c75c5268d4d1257adfc2ac11c930d31e1 -Author: jmc@openbsd.org -Date: Tue Sep 3 06:17:48 2024 +0000 +commit 6fd93060bb2ec35a7f0bf96d1a74104bab49e017 +Author: djm@openbsd.org +Date: Tue Sep 2 09:40:19 2025 +0000 - upstream: envrionment -> environment; + upstream: GssStrictAcceptor was missing from sshd -T output; fix - OpenBSD-Commit-ID: b719f39c20e8c671ec6135c832d6cc67a595af9c + OpenBSD-Commit-ID: 6014049ccfedc48a208e37d5488ade6bdc2d1c44 -commit e66c0c5673a4304a3a9fbf8305c6a19f8653740f +commit d94a9a8c54e9036961c1100c6f445c50ab9b6b40 Author: Damien Miller -Date: Wed Sep 4 15:35:29 2024 +1000 +Date: Tue Sep 2 19:38:39 2025 +1000 - add basic fuzzers for our import of sntrup761 + portable-specific comment grammer/spelling fixes -commit d19dea6330ecd4eb403fef2423bd7e127f4c9828 +commit a0b095fa03d3c08d723a803ce25540fddd955c53 Author: djm@openbsd.org -Date: Tue Sep 3 05:58:56 2024 +0000 +Date: Tue Sep 2 09:34:48 2025 +0000 - upstream: regression test for Include variable expansion + upstream: grammar and typos in comments - OpenBSD-Regress-ID: 35477da3ba1abd9ca64bc49080c50a9c1350c6ca + OpenBSD-Commit-ID: de954daffcd0147ce142d55e8a374810cd19d7ed -commit 8c4d6a628051e318bae2f283e8dc38b896400862 +commit 23a2bb750547a9a5251cbc44c5ceb1d05303befe +Author: Damien Miller +Date: Tue Sep 2 19:30:07 2025 +1000 + + replace remaining manual logging of __func__ + + Use the appropriate log macro that prepends the function name + (e.g. logit_f/debug2_f/etc). + +commit a9b0b69f15e63bc4e8c8b38e24ee85ea076a7e11 Author: djm@openbsd.org -Date: Tue Sep 3 05:29:55 2024 +0000 +Date: Tue Sep 2 09:26:21 2025 +0000 - upstream: allow the "Include" directive to expand the same set of + upstream: replace remaining cases where we manually included __func__ - %-tokens that "Match Exec" and environment variables. + in a debug or error log with the respective *_f log variant - ok dtucker@ + OpenBSD-Commit-ID: 46a280d78bcc0bc98f28e65a30b613366600328f + +commit 19f7cb39eecb4b8f768f37e8294dc3a9142e022b +Author: djm@openbsd.org +Date: Mon Sep 1 23:55:29 2025 +0000 + + upstream: test MaxStatups idempotency; ok dtucker@ - OpenBSD-Commit-ID: 12ef521eaa966a9241e684258564f52f1f3c5d37 + OpenBSD-Regress-ID: b5d713c2709000fa5e41d82c0cf8627e13cb43f9 -commit 51b82648b6827675fc0cde21175fd1ed8e89aab2 +commit c357c4a1e626feba9a968b5f0cb832b989b2d433 Author: djm@openbsd.org -Date: Mon Sep 2 12:18:35 2024 +0000 +Date: Thu Aug 21 05:55:30 2025 +0000 - upstream: missing ifdef + upstream: benchmark more diffie-hellman-group* KEXs - OpenBSD-Commit-ID: 85f09da957dd39fd0abe08fe5ee19393f25c2021 + use current KEX names, i.e. remove the "@openssh.com" where the KEX + has been standardised + + OpenBSD-Regress-ID: a67e9da4efd9a971d39cb2481093f836046f9b7f -commit f68312eb593943127b39ba79a4d7fa438c34c153 +commit 9313233a735733821dfd170b70782fb7da492962 Author: djm@openbsd.org -Date: Mon Sep 2 12:13:56 2024 +0000 +Date: Tue Sep 2 01:03:43 2025 +0000 - upstream: Add experimental support for hybrid post-quantum key exchange + upstream: fix previous - ML-KEM768 with ECDH/X25519 from the Internet-draft: - https://datatracker.ietf.org/doc/html/draft-kampanakis-curdle-ssh-pq-ke-03 + OpenBSD-Commit-ID: 09d95dfb5e064a1d0e74afba8d77474cc1d110a4 + +commit 683d0abe596b069a896f1688f86256f1beeb0cdc +Author: djm@openbsd.org +Date: Mon Sep 1 23:53:16 2025 +0000 + + upstream: Make MaxStartups and PerSourceNetBlockSize first-match-wins - This is based on previous patches from markus@ but adapted to use the - final FIPS203 standard ML-KEM using a formally-verified implementation - from libcrux. + as advertised. bz3859 reported by jan.v.hofmann; ok dtucker - Note this key exchange method is still a draft and thus subject to - change. It is therefore disabled by default; set MLKEM=yes to build it. - We're making it available now to make it easy for other SSH - implementations to test against it. + OpenBSD-Commit-ID: 08f7786f1b3b4a05a106cdbd2dc5f1f2d8299447 + +commit a9a3f025d76f06a6601e6e8d52b468ec467865d9 +Author: djm@openbsd.org +Date: Fri Aug 29 03:50:38 2025 +0000 + + upstream: remove experimental support for XMSS keys; - ok markus@ deraadt@ + ok deraadt markus - OpenBSD-Commit-ID: 02a8730a570b63fa8acd9913ec66353735dea42c + OpenBSD-Commit-ID: 38eaf4df6189acad9e46eddf7cf32d7f6d07df35 -commit 05f2b141cfcc60c7cdedf9450d2b9d390c19eaad -Author: Antonio Larrosa -Date: Fri Aug 23 12:21:06 2024 +0200 +commit 908e9d55139bed19ed87d6fec749974eb42702c6 +Author: caspar@openbsd.org +Date: Mon Aug 18 18:39:33 2025 +0000 - Don't skip audit before exitting cleanup_exit + upstream: ssh_config.5: say "post-quantum" instead of "post quantum - This fixes an issue where the SSH_CONNECTION_ABANDON event is not - audited because cleanup_exit overrides the regular _exit too soon and - as a result, failed auth attempts are not logged correctly. + safe", and rephrase the sentence to make it easier to read. - The problem was introduced in 81c1099d22b81ebfd20a334ce986c4f753b0db29 - where the code from upstream was merged before the audit_event call when - it should have been merged right before the _exit call in order to honor - the comment that just mentions an override of the exit value. + Input djm@, input and OK deraadt@, OK dtucker@ + + OpenBSD-Commit-ID: c3ee4d1cafdcfc20cc0d2f086021efce4b19c075 -commit 16eaf9d401e70996f89f3f417738a8db421aa959 -Author: djm@openbsd.org -Date: Wed Aug 28 12:08:26 2024 +0000 +commit ceca966bde4ab38b2434876416da12fe16747459 +Author: job@openbsd.org +Date: Mon Aug 18 09:16:36 2025 +0000 - upstream: fix test: -F is the argument to specify a non-default + upstream: Delete unused accessor function - ssh_config, not -f (this is sadly not a new bug) + OK dtucker@ - OpenBSD-Regress-ID: 45a7bda4cf33f2cea218507d8b6a55cddbcfb322 + OpenBSD-Commit-ID: 93b59ac088fb254e1189729ece5bb9656d6e810b -commit 10ccf611ab8ecba9ce6b0548c5ccd8c1220baf92 -Author: deraadt@openbsd.org -Date: Fri Aug 23 04:51:00 2024 +0000 +commit 3ef1a87d0a29eac94f32371af628e81eb2e2d817 +Author: Damien Miller +Date: Mon Aug 18 17:00:26 2025 +1000 - upstream: As defined in the RFC, the SSH protocol has negotiable + Fix pledge(2) special casing - compression support (which is requested as the name "zlib"). Compression - starts very early in the session. Relative early in OpenSSH lifetime, privsep - was added to sshd, and this required a shared-memory hack so the two - processes could see what was going on in the dataflow. This shared-memory - hack was soon recognized as a tremendous complexity risk, because it put libz - (which very much trusts it's memory) in a dangerous place, and a new option - ("zlib@openssh.com") was added begins compression after authentication (aka - delayed-compression). That change also permitted removal of the - shared-memory hack. Despite removal from the server, the old "zlib" support - remained in the client, to allow negotiation with non-OpenSSH daemons which - lack the delayed-compression option. This commit deletes support for the - older "zlib" option in the client. It reduces our featureset in a small way, - and encourages other servers to move to a better design. The SSH protocol is - different enough that compressed-key-material attacks like BEAST are - unlikely, but who wants to take the chance? We encourage other ssh servers - who care about optional compression support to add delayed-zlib support. - (Some already do "zlib@openssh.com") ok djm markus + Unbreaks non-OpenBSD platforms + +commit 5e9ca80fe65e407428dc46ed45804724d08b91b7 +Author: Damien Miller +Date: Mon Aug 18 16:47:23 2025 +1000 + + Match version instead of groups in connect-bigconf - OpenBSD-Commit-ID: 6df986f38e4ab389f795a6e39e7c6857a763ba72 + The connect-bigconf makes a giant config file to test config passing + between the sshd subprocesses. Previously it used a bunch of "Match + group" lines to construct a large file. However checking group + membership can be expensive (e.g. if a large groups database is + present or if group lookup is remote via NSS). This could be slow + enough to exceed LoginGraceTime. + + This switches it to "Match version" which is just a string compare + and does just as well for making a giant nonsense config file. -commit aee54878255d71bf93aa6e91bbd4eb1825c0d1b9 -Author: djm@openbsd.org -Date: Thu Aug 22 23:11:30 2024 +0000 +commit 6c84609e5f9ddd49e250d5cf190b2820dbeca178 +Author: Damien Miller +Date: Mon Aug 18 16:47:00 2025 +1000 - upstream: sntrup761x25519-sha512 now has an IANA codepoint assigned, so + depend + +commit 9184fa363687fcb5dac056b093fb3b8e9d327242 +Author: Damien Miller +Date: Mon Aug 18 16:45:15 2025 +1000 + + check for setsockopt IP_TOS in OpenBSD pledge - we can make the algorithm available without the @openssh.com suffix too. ok - markus@ deraadt@ + OpenBSD has recently relaxed the pledge(2) sandbox to allow some + setsockopt options to be changed without the "inet" promise. - OpenBSD-Commit-ID: eeed8fcde688143a737729d3d56d20ab4353770f + This adds compatibility for OpenBSD that predates this relaxation. -commit a76a6b85108e3032c8175611ecc5746e7131f876 -Author: Darren Tucker -Date: Thu Aug 22 20:36:12 2024 +1000 +commit ae44cd74f3a4ac711152f50b2712803ccf785593 +Author: djm@openbsd.org +Date: Mon Aug 18 04:50:35 2025 +0000 - Move rekey test into valgrind-2. + upstream: cast - Now that the rekey test has been optimized it's fast enough to not be in - its own valgrind test, so move it into valgrind-2, which is currently - the quickest of the others, bringing all of them to roughly the same - runtime of ~1.1 hours. + OpenBSD-Commit-ID: d69bd2328513c2dcd99f4f346b77e2bd90cf1964 -commit 7e75e3f57c41b9a6e6401e7674d7c2ff5c33975b -Author: dtucker@openbsd.org -Date: Thu Aug 22 10:21:02 2024 +0000 +commit c2c8bae39380392449ac3297061cbfc486126ad5 +Author: djm@openbsd.org +Date: Mon Aug 18 04:38:21 2025 +0000 - upstream: Use aes128-ctr for MAC tests since default has implicit MAC. + upstream: missing set_log_handler() call in ssh-auth.c, exposed after - Also verify that the Cipher or MAC we intended to use is actually the one - selected during the test. + last commit - OpenBSD-Regress-ID: ff43fed30552afe23d1364526fe8cf88cbfafe1d + OpenBSD-Commit-ID: 09f5c3cf33c18b8ad321edbf96c30ae3deada2b0 -commit ebc890b8b4ba08c84cd1066b7b94b2b11f6c4cb4 +commit 056022261e6cf7eb65bbacac72afe5f4d5945f2c Author: Damien Miller -Date: Thu Aug 22 09:45:49 2024 +1000 +Date: Mon Aug 18 14:22:32 2025 +1000 - fix incorrect default for PasswordAuthentication + depend + +commit b7ee13fbbb4ebafcf71f29685f053ecb97d1bcef +Author: Damien Miller +Date: Mon Aug 18 14:22:18 2025 +1000 + + wrap SIGINFO in ifdef + +commit 289239046b2c4b0076c14394ae9703a879e78706 +Author: djm@openbsd.org +Date: Mon Aug 18 03:43:01 2025 +0000 + + upstream: Make ssh(1) and sshd(8) set IP QoS (aka IP_TOS, IPV6_TCLASS) - merge botch spotted by gsgleason + continually at runtime based on what sessions/channels are open. + + Previously, ssh(1) and sshd(8) would pick a QoS value when they + were started and use it for the whole connection. This could + produce suboptimal choices for the QoS value, e.g. for multiplexed + sessions that started interactive but picked up a sftp client, + or sessions that moved large amounts of data via port forwarding. + + Now the QoS value will change to the non-interactive IPQoS whenever + a "non-interactive" channel is open; basically any channel that lacks + a tty other than agent forwarding. + + This is important now that the default interactive IPQoS is EF + (Expedited Forwarding), as many networks are configured to allow + only relatively small amounts of traffic of this class and they will + aggressively deprioritise the entire connection if this is exceeded. + + NB. because ssh(1) and sshd(8) now change IP_TOS/IPV6_TCLASS + continually via setsockopt(), this commit requires a recent pledge(2) + change that landed recently in the OpenBSD kernel. Please ensure + you have updated to a kernel from within the last two weeks before + updating OpenSSH. + + with job@ deraadt@ + + OpenBSD-Commit-ID: 325fc41717eecdf5e4b534bfa8d66817425b840f -commit 15ace435ea1c2fab2a1cc7d9c3157fe20c776b80 -Author: dtucker@openbsd.org -Date: Wed Aug 21 10:33:27 2024 +0000 +commit dc5147028ff19213a32281dad07bba02e58da3fa +Author: djm@openbsd.org +Date: Mon Aug 18 03:29:11 2025 +0000 - upstream: Some awks won't match on the \r so delete it instead. Fixes + upstream: SIGINFO handler for sshd(8) to dump active - regress in portable on, eg Solaris. + channels/sessions ok deraadt@ - OpenBSD-Regress-ID: 44a96d6d2f8341d89b7d5fff777502b92ac9e9ba + OpenBSD-Commit-ID: 9955cb6d157c6d7aa23a819e8ef61b1edabc8b7d -commit 51c96b6ed627779a04493a8fe25747996a37f3c2 -Author: dtucker@openbsd.org -Date: Wed Aug 21 07:06:27 2024 +0000 +commit f807a598c96be683d97810481e954ec9db6b0027 +Author: djm@openbsd.org +Date: Mon Aug 18 03:28:36 2025 +0000 - upstream: Import regenerated moduli. + upstream: SIGINFO handler for ssh(1) to dump active - OpenBSD-Commit-ID: 5db7049ad5558dee5b2079d3422e8ddab187c1cc + channels/sessions ok deraadt@ + + OpenBSD-Commit-ID: 12f88a5044bca40ef5f41ff61b1755d0e25df901 -commit 25c52f37a82c4da48ec537de37d7c168982b8d6d -Author: dtucker@openbsd.org -Date: Wed Aug 21 06:59:08 2024 +0000 +commit 9b61679d73a8a001c25ab308db8a3162456010cf +Author: djm@openbsd.org +Date: Mon Aug 18 03:28:02 2025 +0000 - upstream: Use curve25519-sha256 kex where possible. + upstream: add channel_report_open() to report (to logs) open - Except where we're explicitly testing a different kex, use - curve25519-sha256 since it's faster than the default and supported even - when configured without OpenSSL. Add a check to ensure that the kex we - intended to test is the one we actually tested. Speeds test up by ~5%. + channels; ok deraadt@ (as part of bigger diff) - OpenBSD-Regress-ID: 3b27fcc2ae953cb08fd82a0d3155c498b226d6e0 + OpenBSD-Commit-ID: 7f691e25366c5621d7ed6f7f9018d868f7511c0d -commit 3eb62b7ba49483c309b483eb9002a679014f3887 -Author: dtucker@openbsd.org -Date: Tue Aug 20 12:36:59 2024 +0000 +commit 80b5ffd22abd4093201939e31d1ea6dc8cc7913a +Author: djm@openbsd.org +Date: Mon Aug 18 01:59:53 2025 +0000 - upstream: Send only as much data as needed to trigger rekeying. Speeds + upstream: make -E a no-op in sshd-auth. Redirecting logging to a - up tests by about 10% in the common case, hopefully more when instrumented - with something like valgrind. + file doesn't work in this program as logging already goes via the parent + sshd-session process. ok dtucker@ - OpenBSD-Regress-ID: 7bf9292b4803357efcf0baf7cfbdc8521f212da1 + OpenBSD-Commit-ID: 73325b9e69364117c18305f896c620a3abcf4f87 -commit cbd3f034bbf7853618fac99d7d868a2250154ea7 +commit 3a039108bd25ff10047d7fa64750ed7df10c717c Author: Damien Miller -Date: Wed Aug 21 09:18:29 2024 +1000 - - simplify sshkey_prekey_alloc(); always use mmap +Date: Mon Aug 18 13:46:37 2025 +1000 -commit 4442bbc2fc661277a6dabfedb756a7e15ee8b8b8 -Author: dtucker@openbsd.org -Date: Tue Aug 20 09:15:49 2024 +0000 - - upstream: Merge AEAD test into main test loop. + allow some socket syscalls in seccomp sandbox - Removes 3 duplicate tests and speeds overall test up by about 1%. + Allow getsockname(2), getpeername(2) and getsockopt(2). - OpenBSD-Regress-ID: 5e5c9ff3f7588091ed369e34ac28520490ad2619 + Also allow setsockopt(2) but only IP_TOS and IPV6_TCLASS. + + Note that systems that use the older socketcall(2) mux syscall will + not have IP_TOS and IPV6_TCLASS allowlisted. On these platforms, + these calls will be soft-blocked (i.e. will fail rather than + terminate the whole process with a sandbox violation). + + Needed for upcoming IPQoS change; ok dtucker@ -commit 829976a63fd1efae3a4c3e7c16fded59d92edb67 -Author: dtucker@openbsd.org -Date: Tue Aug 20 09:02:45 2024 +0000 +commit a00f5b02e171bc6d6fb130050afb7a08f5ece1d8 +Author: Damien Miller +Date: Mon Aug 18 13:44:53 2025 +1000 - upstream: Set a default RekeyLimit of 256k. + handle futex_time64 properly in seccomp sandbox - Used unless overridden by a command-line flag, which simplifies some of - the ssh command lines. + Previously we only allowed __NR_futex, but some 32-bit systems + apparently support __NR_futex_time64. We had support for this + in the sandbox, but because of a macro error only __NR_futex was + allowlisted. - OpenBSD-Regress-ID: e7cffa57027088e10336e412b34113969f88cb87 + ok dtucker@ -commit 57d02c9ea36aebad4e7146d46e041b6b2e582f7f +commit 32deb00b38b4ee2b3302f261ea1e68c04e020a08 Author: dtucker@openbsd.org -Date: Tue Aug 20 07:52:43 2024 +0000 +Date: Thu Aug 14 10:03:44 2025 +0000 - upstream: Add Compression=no to default ssh_config. + upstream: Cast serial no for %lld to prevent compiler warnings on some - All of the rekey tests use it (otherwise the encrypted byte counts would - not match) so this lets us simplify the command lines. + platforms. - OpenBSD-Regress-ID: dab7ce10f4cf6c68827eb8658141272aab3ea262 + OpenBSD-Commit-ID: afadd741622f16c6733d461c0d6053ed52868a57 -commit 7254eb26f7c0772c4b47c3b32f6d1b15855cdd8c +commit 883886c959ecab152650e231335857eb3193c662 Author: dtucker@openbsd.org -Date: Tue Aug 20 07:41:35 2024 +0000 +Date: Thu Aug 14 09:44:39 2025 +0000 - upstream: Remove duplicate curve25519-sha256 kex. + upstream: Cast serial no for %lld to prevent compiler warnings on some - curve25519-sha256@libssh.org is the pre-standardization name for the same - thing, so remove it as a duplicate. Speeds up test by a tiny amount. + platforms. - OpenBSD-Regress-ID: 5a5ee5fa1595a6e140b1cc16040bedf5996a5715 + OpenBSD-Commit-ID: 46c6063284d318f7e4dc922479a3e394c94b0588 -commit 749896b874928c2785256cae4d75161dc3bfcc7d +commit fde5a4d2cd01bea700439fa6d5bbad88e65c99bd Author: dtucker@openbsd.org -Date: Tue Aug 20 07:27:25 2024 +0000 +Date: Thu Aug 14 09:26:53 2025 +0000 - upstream: Unnest rekey param parsing test and use ssh not sshd. + upstream: Cast serial no for %lld to prevent compiler warnings on some - ssh uses the same parsing code, now has "-G" to dump its config and is - slightly faster to start up. This speeds up the test slightly (~5%) in the - common case but should help more during instrumented tests, eg under - valgrind, where startup costs are magnified. + platforms. - OpenBSD-Regress-ID: 07c3acaf4c728e641033071f4441afc88141b0d0 + OpenBSD-Commit-ID: 15644234b58abc9c6da2994f0422a5aa344a9e89 -commit 2b1762115481ff2b7a60fd4db2ae69b725437462 -Author: djm@openbsd.org -Date: Tue Aug 20 11:10:04 2024 +0000 +commit ab5074dfb614e3801fecbd376d8ed4cea613c629 +Author: sthen@openbsd.org +Date: Tue Aug 12 11:09:48 2025 +0000 - upstream: actually use the length parameter that was passed in rather - - than a constant (this makes no difference in practice because the length is - always the same); reported by martin AT nmkd.net + upstream: fix typo, ok markus dtucker - OpenBSD-Commit-ID: 4aecce232c2fe9b16e9217ff6bcb3c848d853e7e + OpenBSD-Commit-ID: 8f223da7633752162c64a659c6cf55202703d870 -commit d922762ca16a7381131b242f49d7376c41fabcb5 -Author: Damien Miller -Date: Tue Aug 20 13:55:30 2024 +1000 +commit 8b6c1f402feb9eb6438003a312d7ffe8d5669896 +Author: deraadt@openbsd.org +Date: Mon Aug 11 14:37:43 2025 +0000 - private key coredump protection for Linux/FreeBSD + upstream: Handle localtime_r() failure by return "UNKNOWN-TIME" - platforms not supporting coredump exclusion using mmap/madvise flags - fall back to plain old malloc(3). + which is only used in user-visible contexts. freebsd 288773 shows their + localtime_r() has failed at least once for unknown reason. discussed with djm + + OpenBSD-Commit-ID: 68f4c92d46b2578d4594b0ed940958d597fd61ac -commit cc048ca536d6bed6f2285b07040b0d57cd559ba5 +commit 0e1b8aa27f7c86d412c9e54ad9e2cae30d9ddab4 Author: djm@openbsd.org -Date: Tue Aug 20 03:48:30 2024 +0000 +Date: Mon Aug 11 10:55:38 2025 +0000 - upstream: place shielded keys (i.e. keys at rest in RAM) into memory + upstream: ssh(1): add a warning when the connection negotiates a - allocated using mmap(3) with MAP_CONCEAL set. This prevents exposure of the - key material in coredumps, etc (this is in addition to other measures we take - in this area). + non-post quantum safe key agreement algorithm. - ok deraadt@ + Controlled via a new WarnWeakCrypto ssh_config option, defaulting + to on. This option might grow additional weak crypto warnings in + the future. - OpenBSD-Commit-ID: cbbae59f337a00c9858d6358bc65f74e62261369 + More details at https://openssh.com/pq.html + + mostly by deraadt@ feedback dtucker@ ok deraadt@ + + OpenBSD-Commit-ID: 974ff243a1eccceac6a1a9d8fab3bcc89d74a2a4 -commit a0b35c791cad1f85481b23ba46373060292e1c80 +commit 2ebc6384258b58ace0ad2adb2593744f62749235 Author: djm@openbsd.org -Date: Sat Aug 17 08:35:04 2024 +0000 +Date: Wed Aug 6 23:44:09 2025 +0000 - upstream: mention that ed25519 is the default key type generated and + upstream: all state related to the ssh connection should live in - clarify that rsa-sha2-512 is the default signature scheme when RSA is in use. - Based on GHPR505 from SebastianRzk + struct ssh or struct packet_state; one static int escaped this rule, so move + it to struct packet_state now. - OpenBSD-Commit-ID: 1d90df71636a04601685d2a10a8233bcc8d4f4c5 + ok millert tb + + OpenBSD-Commit-ID: bd6737168bf61a836ffbdc99ee4803468db90a53 -commit 127a50f2c80572ed1a021feb11ecf941e92cbbef -Author: djm@openbsd.org -Date: Sat Aug 17 08:23:04 2024 +0000 +commit 60b909fb110f77c1ffd15cceb5d09b8e3f79b27e +Author: dtucker@openbsd.org +Date: Wed Aug 6 11:22:53 2025 +0000 - upstream: fix minor memory leak in Subsystem option parsing; from + upstream: Improve sentence. ok djm@ - Antonio Larrosa via GHPR515 - - OpenBSD-Commit-ID: fff3bbefd1b2c45c98cbe45c6b857b15d8a2d364 + OpenBSD-Commit-ID: 9c481ddd6bad110af7e530ba90db41f6d5fe2273 -commit 171427261d2079941eb1041079dbae875da37cbc +commit 9ffa98111dbe53bf86d07da8e01ded8c5c25456b Author: djm@openbsd.org -Date: Sat Aug 17 08:09:50 2024 +0000 +Date: Wed Aug 6 04:53:04 2025 +0000 - upstream: fix swapping of source and destination addresses in some sshd + upstream: when refusing a certificate for user authentication, log - log messages + enough information to identify the certificate in addition to the reason why + it was being denied. Makes debugging certificate authz problems a bit easier. - OpenBSD-Commit-ID: 24d4cbb86325275df1f037545aa3b91456e52d25 + ok dlg@ + + OpenBSD-Commit-ID: 4c4621b2e70412754b3fe7540af8f4bf02b722b1 -commit 2a50a8f1fa57857a5e124a2280bcf61cc63c77f7 -Author: Darren Tucker -Date: Sat Aug 17 11:10:19 2024 +1000 +commit 2a31009c36eb2da412c2784fe131fcb6ba800978 +Author: job@openbsd.org +Date: Tue Aug 5 09:08:16 2025 +0000 - Add compat functions for EVP_Digest{Sign,Verify}. + upstream: Use the operating system default DSCP marking for - This should make LibreSSL 3.1.x through 3.3.x work again. Code from - tb@, ok djm@. Restore the test configs covering those. + non-interactive traffic + + It seems the CS1 traffic class mark is considered ambiguous and therefore + somewhat unhelpful (see RFC 8622 for more considerations). But, the new + 'LE' scavenger class (also proposed in RFC 8622) offers high probability + of excessive delays & high packet loss, which would be inappropriate + for use with, for example, X11 forwardings. In fact, it is not known to + SSH what's appropriate because SSH is not aware of the content of what + passing through session forwardings. Therefore, no marking is appropriate. + Non-interactive traffic simply is best effort. + + OK djm@ deraadt@ + + OpenBSD-Commit-ID: db1da1a432ecd53fc28feb84287aedb6bec80b01 -commit 1c3a7145260e03037cc18715b883880836fd122d -Author: Philip Hands -Date: Thu Aug 8 13:03:51 2024 +0200 +commit 6ebd472c391a73574abe02771712d407c48e130d +Author: djm@openbsd.org +Date: Tue Aug 5 04:00:15 2025 +0000 - make sure that usage & man page match + upstream: a bunch of the protocol extensions we support now have RFCs - SSH-Copy-ID-Upstream: da5b1abe55b72a16e0430e7598e1573da01779c0 + and I-Ds that are more complete and detailed than what we have in the + PROTOCOL.* files. Refer to these when possible instead of documenting them + here. + + OpenBSD-Commit-ID: 4fa5b0fcf5d5f24093d33d9e82c7ca4850d50d70 -commit cd0d681645b9adcf2467e7838bfd9d5142de4c4e -Author: Philip Hands -Date: Thu Aug 8 13:01:47 2024 +0200 +commit ec3465f59c651405e395092f3ad606f8992328d8 +Author: job@openbsd.org +Date: Thu Jul 31 11:23:39 2025 +0000 - update copyright notices + upstream: Deprecate support for IPv4 type-of-service (TOS) IPQoS - Bump the year to 2024, but also reflect the fact that hands.com Ltd. has - been wound up in the UK, and its assets (including this copyright) have - now reverted to its owner, Philip Hands. + keywords - SSH-Copy-ID-Upstream: 0e4c4d072747a6568b11a790c29dd1b4ce663d7f + Type of Service (ToS) was deprecated in the late nineties and replaced + with the Differentiated Services architecture. Diffserv has significant + advantages for operators because this mechanism offers more granularity. + + OpenSSH switched its default IPQoS from ToS to DSCP values in 2018. + + IPQoS configurations with 'lowdelay', 'reliability', or 'throughput' will be + ignored and instead the system default QoS settings apply. Additionally, a + debug message is logged about the deprecation with a suggestion to use DSCP. + + with/OK deraadt@ sthen@ djm@ + + OpenBSD-Commit-ID: 40c8c0c5cb20151a348728703536af2ec1c754ba -commit 7fc9ccdce18841ebd0a97e31e43258512ab32a32 -Author: Philip Hands -Date: Sun Aug 4 20:45:00 2024 +0200 +commit 65909fa114e7dd7511800db2b7bacb8774afe887 +Author: job@openbsd.org +Date: Thu Jul 31 09:38:41 2025 +0000 - restore optionality of -i's argument + upstream: Set default IPQoS for interactive sessions to Expedited - SSH-Copy-ID-Upstream: f70e3abb510e4eeb040b47894e41828246c1b720 + Forwarding (EF) + + Marking interactive session data with DSCP value EF (RFC3246, RFC3247) + helps inform the network on relative priority compared to other traffic. + This is especially useful for differentiated treatment over wireless media. + + Following the reconciled IETF Diffserv to IEEE 802.11 mappings (RFC 8325), + traffic marked with DSCP value EF maps to User Priority 6 in QoS Control, + in turn mapping to the high priority WMM AC_VO access category. + + OK djm@ + + OpenBSD-Commit-ID: aadda7b9da794d70d7c6b381a861a0610afce1b3 -commit c37aa7012b1a3c2c322fd19e71310aadc90fc674 -Author: Philip Hands -Date: Fri Aug 2 15:52:07 2024 +0200 +commit d1c6c67a50fc957010fa027c6ab970424e9b9142 +Author: Darren Tucker +Date: Sat Aug 2 14:49:00 2025 +1000 - avoid exploring .ssh/id*.pub subdirectories - - SSH-Copy-ID-Upstream: 0b9e08b7707ad16de3c8e6a0410d9f42fbd56997 + Disable security key tests for bigendian interop -commit 777dce9e2e0d12f7e81e162f77749f30899869fe -Author: Philip Hands -Date: Fri Aug 2 10:07:11 2024 +0200 +commit e85248df3f1073343da87a6b00512e6a1e4a863d +Author: Darren Tucker +Date: Sat Aug 2 12:51:42 2025 +1000 - ensure that we're always told the source of keys + Comment out atime restore test. - SSH-Copy-ID-Upstream: 1bee96f4793e8ec3fab9f9361204ae58f5cc7cae + This works on filesystems mounted 'noatime', but on others the stat() + resets atime causing the test to fail. -commit fb94fd2339848e40cad6c9bb42b822244cc1a7bc -Author: Philip Hands -Date: Wed Jul 31 23:19:51 2024 +0200 +commit b1c4cedbee107dc611ce091f27ea9f1de28ee378 +Author: Darren Tucker +Date: Fri Aug 1 19:29:00 2025 +1000 - add $HOME to ERROR if one cannot write to ~/.ssh + Replace fbsd64ppc VM with physical host. - SSH-Copy-ID-Upstream: ebef3e9c06e0447bff06e9d84b33023cf592e0ba + Run 64bit bigendian interop test on NetBSD arm64be instead. -commit eb5aafa1ffaeee75799141ec5ded406a65ec7d18 -Author: Philip Hands -Date: Wed Jul 31 23:19:03 2024 +0200 +commit 284abbed9a8d815b1ec5e96aff885d77e26537e7 +Author: dtucker@openbsd.org +Date: Wed Jul 30 10:17:13 2025 +0000 - assert that SCRATCH_DIR is a writable directory + upstream: Plug leak in case where sigp is passed as NULL. Coverity CID - SSH-Copy-ID-Upstream: ecb2b9d10883b9a16df56c83896c9bb47a80cde2 + 483725, ok djm@ + + OpenBSD-Commit-ID: 47cf7b399c84e102b670b9f97ab6926c9a7256b5 -commit abcc460a2af46f0d812f8433d97a8eae1d80724c -Author: Philip Hands -Date: Wed Jul 31 23:17:54 2024 +0200 +commit dc630e6d81be8aa495254839731e4f3521cf9e31 +Author: djm@openbsd.org +Date: Wed Jul 30 04:27:42 2025 +0000 - quote to avoid potential for word splitting + upstream: unbreak WITH_OPENSSL=no builds, also allowing ed25519 - SSH-Copy-ID-Upstream: f379adbe06ac2ef1daf0f130752234c7f8b97e3c + keys to be used via PKCS#11 when OpenSSH is built without libcrypto. + + OpenBSD-Commit-ID: ecf26fdf7591bf2c98bac5136fbc36e0b59c3fc2 -commit b3f91411fd1473605f74c40c1a91a024c7171e27 -Author: Philip Hands -Date: Wed Jul 31 23:15:11 2024 +0200 +commit a5bec2cdfc4f38ddb6211809851aae29ba99a35a +Author: djm@openbsd.org +Date: Wed Jul 30 04:19:17 2025 +0000 - ensure ERROR output goes to STDERR + upstream: fix variable name in disabled code - SSH-Copy-ID-Upstream: ac394b05eead3b91feb7c2ae4129a3e9b892f1e2 + OpenBSD-Commit-ID: 5612e979575d5da933c8b720d296423fd84392f5 -commit 674b8f30f0dbacd787eb1e4e7e1ece34b5543d8f -Author: Philip Hands -Date: Thu Aug 1 14:03:06 2024 +0200 +commit 5e4bfe6c16924b1c21a733f3e218cfcba98e301e +Author: Damien Miller +Date: Sat Jul 26 19:19:46 2025 +1000 - avoid extra space when no arg given to -i option - - SSH-Copy-ID-Upstream: feca9e67e6e37c5653445d1c733569d7abb1770e + more ec/ed25519 fixing -commit 0efa0e1c41427c0c6ba839a18c72c1afcd7b7cc0 -Author: Philip Hands -Date: Wed Jul 31 23:28:36 2024 +0200 +commit 2603098959eff55cbe188c3dfcbe5302808a80fc +Author: Damien Miller +Date: Sat Jul 26 14:27:53 2025 +1000 - put the -i before -[pP] (matching man pages) - - The man pages (ssh, sftp & ssh-copy-id) all list -i before the port - setting, so make the output match that order, which also seems more - natural with the port being next to the server. + repair build for libcrypto without ed25519 support + +commit a729163c56ecc002c0cb04db56e7d86ceec2e8b0 +Author: djm@openbsd.org +Date: Sat Jul 26 01:53:31 2025 +0000 + + upstream: regression tests for Ed25519 keys in PKCS#11 tokens - SSH-Copy-ID-Upstream: 34d5d614172c78f9a42249466c4b81975b8883a1 + OpenBSD-Regress-ID: 50067c0716abfea3a526b4a0c8f1fe15e7665c0f -commit 87831345e9745f2d13bd7a4a7972809f6788f331 -Author: Shreyas Mahangade -Date: Mon Jul 29 15:26:05 2024 +0000 +commit 361ff0ca308ac02449e71689fc5ea72114db43db +Author: djm@openbsd.org +Date: Sat Jul 26 01:51:44 2025 +0000 - Minor space issue fixed + upstream: Support ed25519 keys hosted on PKCS#11 tokens. - SSH-Copy-ID-Upstream: 335e44d7be78b03962a54c3a5c99a2ff45294a54 + Tested on Yubikeys and against SoftHSM2. + + feedback/ok tb@ + + OpenBSD-Commit-ID: 90ddb6529f2e12e98e8bba21d8592e60579ce2e4 -commit 2f3010f4736b4b3f5c10a4be97a24e90ff04c5e7 -Author: Shreyas Mahangade -Date: Mon Jul 29 16:55:28 2024 +0530 +commit 2b530cc3005a71c5ba6b712978872fc9c147439c +Author: djm@openbsd.org +Date: Fri Jul 25 13:06:07 2025 +0000 - Show identity file in 'ssh' command + upstream: update our PKCS#11 API header to v3.0; - - Previously no identity file is shown in "ssh" command output on the line "Now try logging into the..." - - This commit makes sure whenever "ssh-copy-id" with "-i" is invoked, it also reflects in "ssh" command + feedback/ok tb@ - SSH-Copy-ID-Upstream: 58e022ec26cb2315eb3be581d01e0ba787082428 + OpenBSD-Commit-ID: e67fa6a26e515c2b1fb7b0d1519d138aafb3e017 -commit a13856374b894397a7682b32257ed0bf67cfede9 +commit 550d2a4a66c50f7641563a63b900761d99efb24a Author: Damien Miller -Date: Fri Aug 16 08:30:20 2024 +1000 +Date: Fri Jul 25 23:04:33 2025 +1000 - more OPENSSL_HAS_ECC + another attempt at fixing !EC builds -commit 4da2a1a7f648979bea6eaf3b17f5f250faed4afc -Author: Damien Miller -Date: Thu Aug 15 23:35:54 2024 +1000 +commit ed1e370d84e9dc39bc31c19cca12222d991fdc6f +Author: dtucker@openbsd.org +Date: Fri Jul 25 11:50:45 2025 +0000 - fix merge botch that broke !OPENSSL_HAS_ECC + upstream: Don't snprintf a NULL since not all platforms support it. + + OpenBSD-Commit-ID: 6e0c268e40047e96fab6bc56dc340580b537183b -commit 2c53d2f32b8e3992b61682c909ae5bc5122b6e5d +commit eedab8db12d57c4f4583f6b60e48a4ce25b47b9c Author: Damien Miller -Date: Thu Aug 15 15:09:45 2024 +1000 +Date: Fri Jul 25 16:21:43 2025 +1000 - missed OPENSSL_HAS_ECC case + unbreak !EC builds -commit 342dd7a219f39119b8b686b5aaa99c8e15ede368 -Author: Damien Miller -Date: Thu Aug 15 15:06:55 2024 +1000 +commit 203f5ac6cfa0e257db7509d4bb830e8a4bba6211 +Author: djm@openbsd.org +Date: Thu Jul 24 06:04:47 2025 +0000 - retire testing aginst older LibreSSL versions + upstream: test code now needs to link ssh-pkcs11-client.c any time - libressl prior to 3.4.x lack support for the EVP_DigestSign and - EVP_DigestVerify APIs that we need now that sshkey is converted - to EVP_PKEY. + sshkey.c is included - If someone makes a good case for why we should support these versions - then we could bring back support with wrappers. + OpenBSD-Regress-ID: 9d07188eae9a96801c3150b3433bb220626d4443 + +commit 33b4f05c8ddab24aa6c47afb313b8cbd0d4b77f4 +Author: Damien Miller +Date: Fri Jul 25 12:47:17 2025 +1000 -commit a7c6ea8eebe0f179141ec5dbf0c9e5354417930f + update clang-16 -> clang-19 + +commit 03e9e993ef1ef5accc6457152278cab5988f9b3d Author: Damien Miller -Date: Thu Aug 15 12:44:17 2024 +1000 +Date: Fri Jul 25 12:46:59 2025 +1000 - sync TEST_MALLOC_OPTIONS for OpenBSD + include ssh-pkcs11-client.o as common dep -commit 60c2cf22e8f64f35d8b1175e4671257313f2e4d3 +commit 2f5269938a8e4769f484c9d45419a86529078ede Author: Damien Miller -Date: Thu Aug 15 12:43:47 2024 +1000 +Date: Fri Jul 25 12:46:10 2025 +1000 - remove gratuitious difference from OpenBSD + remove vestigial stub -commit 339c4fc60a6250429d41fa8713f783d82aad4551 +commit bf33a73c40522ce60961d4fff316a7187fb06ca0 Author: djm@openbsd.org -Date: Thu Aug 15 00:52:23 2024 +0000 +Date: Thu Jul 24 23:27:04 2025 +0000 - upstream: adapt to EVP_PKEY conversion + upstream: this should include stdlib.h explicitly - OpenBSD-Regress-ID: 0e2d4efb0ed0e392e23cd8fda183fe56531ac446 + OpenBSD-Commit-ID: 1c0cc5c3838344b33ae4ab7aa62c01530357bf29 -commit 63a94f99b9d7c8a48182a40192e45879d1ba8791 +commit 9f8ccc3b81b53324cc489f3fe00f03c329c0acb2 Author: djm@openbsd.org -Date: Fri Jul 19 04:33:36 2024 +0000 +Date: Thu Jul 24 06:59:51 2025 +0000 - upstream: test transfers in mux proxy mode too + upstream: less stale reference to PKCS#1 1.5 hash OIDs; feedback - OpenBSD-Regress-ID: 2edfc980628cfef3550649cab8d69fa23b5cd6c4 + from tb@ + + OpenBSD-Commit-ID: 9fda77978491a130a7b77d87d40c79277b796721 -commit 7bdfc20516e288b58c8c847958059c7b141eeff9 +commit 1641ab8744f500f55f12155d03f1a3116aaea374 Author: djm@openbsd.org -Date: Thu Aug 15 00:51:51 2024 +0000 +Date: Thu Jul 24 06:12:08 2025 +0000 - upstream: Convert RSA and ECDSA key to the libcrypto EVP_PKEY API. - - DSA remains unconverted as it will be removed within six months. - - Based on patches originally from Dmitry Belyavskiy, but significantly - reworked based on feedback from Bob Beck, Joel Sing and especially - Theo Buehler (apologies to anyone I've missed). + upstream: factor out encoding of a raw ed25519 signature into its - ok tb@ + ssh form into a separate function - OpenBSD-Commit-ID: d098744e89f1dc7e5952a6817bef234eced648b5 + OpenBSD-Commit-ID: 3711c6d6b52dde0bd1f17884da5cddb8716f1b64 -commit 0af06e2c5b898992a18c74333e75a0136506acc6 -Author: tobias@openbsd.org -Date: Wed Aug 14 15:42:18 2024 +0000 +commit a8c0e5c871c0c7ee5ae93e353b1499a53c09c71d +Author: djm@openbsd.org +Date: Thu Jul 24 05:44:55 2025 +0000 - upstream: Reorder calloc arguments + upstream: Help OpenSSH's PKCS#11 support kick its meth habit. - The first argument should be the amount, the second argument should be the - element size. Fixing this also silences some gcc compiler warnings for - portable. + The PKCS#11 code in OpenSSH used the libcrypto public key method API + (e.g. the delightfully named RSA_meth_free()) to delegate signing + operations to external keys. This had one advantage - that it was + basically transparent to callers, but also had a big disadvantage - + that we'd manually have to track the method implementations, their + state and their relationships to the underlying PKCS#11 objects. - Spotted with Benny Baumann (BenBE at geshi dot org). + This rips this out and replaces it with explicit delegation to + PKCS#11 code for externally hosted keys via the ssh-pkcs11-helper + subprocess. This is very similar to how we handle FIDO keys in + OpenSSH (i.e. via ssh-sk-helper). All we need to track now is a + much simpler mapping of public key -> helper subprocess. - ok djm@ + Kicking our libcrypto meth dependency also makes it much easier + to support Ed25519 keys in PKCS#11, which will happen in a subsequent + commit. - OpenBSD-Commit-ID: 711ad6f7bd7fb48bf52208f2cf9f108cddb6d41a + feedback / ok tb@ + + OpenBSD-Commit-ID: a5a1eaf57971cf15e0cdc5a513e313541c8a35f0 -commit 56ce0aa3c6cf28d9fcbce3207457abeac91b5050 -Author: tobias@openbsd.org -Date: Wed Aug 14 15:40:30 2024 +0000 +commit 259c66aebe4e1f9d60e548f728ff74083bcccddf +Author: Darren Tucker +Date: Thu Jul 24 22:02:49 2025 +1000 - upstream: Extend sshbuf validation + Remove DEBUG_ACTIONS variable. - Multiple sshbuf structs can be linked through a parent/child relationship. - Make sure that a single sshbuf cannot be its own parent. If this would ever - happen, it would result in reference counting issues. + If needed it can be set in github if needed. + +commit 40fb2dc4ece76c8f0c624d90a17bc1bbf47f3729 +Author: djm@openbsd.org +Date: Wed Jul 23 05:07:19 2025 +0000 + + upstream: add a ssh_config RefuseConnection option that, when - This is a cheap way of testing this with very little overhead. It does not - detect A->B->A linkages though for performance reason and the fact that it - takes a programming error for this to occur anyway. + encountered while processing an active section in a configuration file, + terminates ssh(1) with an error message that contains the argument to the + option. - Authored with Benny Baumann (BenBE at geshi dot org). + This may be useful for expressing reminders or warnings in config + files, for example: - ok djm@ + Match host foo + RefuseConnection "foo is deprecated, use splork instead" - OpenBSD-Commit-ID: fb3fa9ee2cad3c7e842ebadfd7f5db220c4aaf16 + ok djg + + OpenBSD-Commit-ID: 5b0072fcd08ad3932ab21e27bbaa66b008d44237 -commit fc48ddf6998188517af42dce807e2088b6a0c0be -Author: tobias@openbsd.org -Date: Wed Aug 14 15:37:11 2024 +0000 +commit defc806574d2256036d69a291caf0f3484844de6 +Author: miod@openbsd.org +Date: Sat Jul 12 05:28:33 2025 +0000 - upstream: Use freezero for better readability + upstream: Add missing inter-library dependencies to LDADD and - It has the same meaning as the current pair of calling explicit_bzero - and free. Spotted with Benny Baumann (BenBE at geshi dot org). - - ok djm@ + DPADD. ok tb@ deraadt@ - OpenBSD-Commit-ID: 939fbe9ccf52d0d48c5fa53694d6f3bb9927970c + OpenBSD-Commit-ID: a05e13a7e2c0b65bb4b47184fef731243431c6ff -commit 1ff6907ec26dac6ac59fe9fe232899a63b4c14d8 -Author: tobias@openbsd.org -Date: Wed Aug 14 15:35:23 2024 +0000 +commit e6805e2a6b33e001e1a7257b85ab779fd592a578 +Author: Jan Tojnar +Date: Thu May 18 16:30:35 2023 +0200 - upstream: Fix typo in comment + Add gnome-ssh-askpass4 for GNOME 40+ - Spotted with Benny Baumann (BenBE at geshi dot org). + GTK 3 has been in maintenance mode for a while now, and it is on the road + to being abandoned. As a result, the dialogue looks out of place on modern + systems. - ok djm@ + We could port it to GTK 4 but without the program being registered as an + application (i.e. having a .desktop file), GNOME Shell would ask for + permission to grab input every time. - OpenBSD-Commit-ID: 829160ac8ef3ad3409695ce3a3ade835061cae57 + Let’s instead use the GNOME Shell’s native prompt through the unstable + Gcr API. -commit 487faaed8f3bb9ffb19e8f807a3da72895b16421 -Author: dlg@openbsd.org -Date: Wed Jul 31 12:00:18 2024 +0000 +commit f9dc519259804702cab0fa0ca8b193a360e3ec38 +Author: Damien Miller +Date: Fri Jul 11 17:20:27 2025 -0700 - upstream: add a random amount of time (up to 4 seconds) to the + let ga_init() fail gracefully if getgrouplist does - grace login time. + Apparently getgrouplist() can fail on OSX for when passed a non-existent + group name. Other platforms seem to return a group list consisting of + the numeric gid passed to the function. - ok deraadt@ djm@ + This makes ga_init() handle this failure case gracefully, where it will + return success but with an empty group list array. - OpenBSD-Commit-ID: abd3c57aaa5861517529b322df79b6be35ee67f4 + bz3848; ok dtucker@ -commit 2865f5b7520bed3e74fbbb5f8d7a44193d7a4314 -Author: naddy@openbsd.org -Date: Fri Jul 26 15:24:49 2024 +0000 +commit f01a899b92ab8c5e6ff71214658bd09636c47e87 +Author: djm@openbsd.org +Date: Fri Jul 11 23:26:59 2025 +0000 - upstream: document the reduced logingrace penalty + upstream: add a "Match Group NoSuchGroup" to exercise groupaccess.c - OpenBSD-Commit-ID: 9b63e0e3599d524ddc10edc4f978081382c3548b + OpenBSD-Regress-ID: 7ff58e6f0eb21eb9064dd0cfa78c3b6f34b5f713 -commit 1ec0a64c5dc57b8a2053a93b5ef0d02ff8598e5c -Author: Darren Tucker -Date: Sun Jul 28 21:26:51 2024 +1000 +commit 1052fa62b35e0bb25b0c1efb9fdd7870e4a68ab6 +Author: Damien Miller +Date: Fri Jul 11 15:36:49 2025 -0700 - Explicitly install libssl-devel cygwin. - - Should fix CI tests for cygwin default config. + more diagnostics when getgrouplist fails -commit 0bf6e5bb750b66b25c20a1c5a471f91850de3748 +commit eddd1d2daa64a6ab1a915ca88436fa41aede44d4 Author: djm@openbsd.org -Date: Thu Jul 25 23:44:01 2024 +0000 +Date: Fri Jul 4 09:51:01 2025 +0000 - upstream: reduce logingrace penalty. + upstream: Fix mistracking of MaxStartups process exits in some - A single forgotton login that times out should be below the penalty - threshold. + situations. At worst, this can cause all MaxStartups slots to fill and sshd + to refuse new connections. - ok deraadt/claudio + Diagnosis by xnor; ok dtucker@ - OpenBSD-Commit-ID: cee1f7d17597c97bff8e5092af5d136fdb08f81d + OpenBSD-Commit-ID: 10273033055552557196730f898ed6308b36a78d -commit 29fb6f6d46b67770084b4f12bcf8a01bd535041b -Author: djm@openbsd.org -Date: Thu Jul 25 22:40:08 2024 +0000 +commit c971f3d93efe4c00d73b276cdbab66e7c66c9b5c +Author: Darren Tucker +Date: Sat Jul 5 20:50:50 2025 +1000 - upstream: Fix proxy multiplexing (-O proxy) bug - - If a mux started with ControlPersist then later has a forwarding added using - mux proxy connection and the forwarding was used, then when the mux proxy - session terminates, the mux master process will send a channel close to the - server with a bad channel ID and crash the connection. - - This was caused by my stupidly reusing c->remote_id for mux channel - associations when I should have just added another member to struct channel. - - ok markus@ + Add include for gssapi definitions. - OpenBSD-Commit-ID: c9f474e0124e3fe456c5e43749b97d75e65b82b2 + Patch from dbelyavs at redhat.com via bz#3846. -commit 53d1d307438517805989c7d5616d752739a97e03 +commit 007b69f21cf9e64125b241d4411a5e47f5028aa8 Author: djm@openbsd.org -Date: Thu Jul 18 01:47:27 2024 +0000 +Date: Fri Jul 4 07:52:17 2025 +0000 - upstream: mention mux proxy mode + upstream: add a regress test for configurations > 256KB - OpenBSD-Commit-ID: fd77a77779f06d316a314e4540dc57c93fc3369a - -commit a9b90859d252c2f5a24142f985d38610ac74685f -Author: jsg@openbsd.org -Date: Sun Jul 14 10:19:23 2024 +0000 - - upstream: fix double word; ok dtucker@ + mostly by Dmitry Belyavskiy - OpenBSD-Commit-ID: e6aff005914fa350b896d2be030be3d3b56ec0e8 + OpenBSD-Regress-ID: fcedb249e4cf2447e078a839877f99730ee79024 -commit b05fda224bbcd2f641254534ed2175c42487f3c8 -Author: Darren Tucker -Date: Thu Jul 25 17:59:35 2024 +1000 +commit 0cf38d74463bcf80510e7fd1b3d9328e7d91eb00 +Author: djm@openbsd.org +Date: Fri Jul 4 07:47:35 2025 +0000 - Check for SA_RESTART before using it. + upstream: the messaging layer between sshd-session and sshd-auth had a - ok djm@ - -commit c276672fc0e99f0c4389988d54a84c203ce325b6 -Author: Yuichiro Naito -Date: Wed Sep 1 10:19:32 2021 +0900 - - Class-imposed login restrictions + maximum message size of 256KB. Some people apparently have configurations + larger than this and would hit this limit. - If the following functions are available, - add an additional check if users are allowed to login imposed by login class. + Worse, there was no good logging that could help diagnose what was + going wrong. - * auth_hostok(3) - * auth_timeok(3) + So this bumps the maximum message size to 4MB and implements an early + check (usable via the sshd -t test mode) that will report it to the + user where it is hopefully more visible. - These functions are implemented on FreeBSD. + bz3808, reported by Dmitry Belyavskiy, ok dtucker@ + + OpenBSD-Commit-ID: 69c303fb68cbd1a4735936835d67a71e7b57f63b -commit 7717b9e9155209916cc6b4b4b54f4e8fa578e889 +commit fd10cea0f16e928ae2b52fbeadccd475d0438eb4 Author: djm@openbsd.org -Date: Wed Jul 10 21:58:34 2024 +0000 +Date: Fri Jul 4 00:17:55 2025 +0000 - upstream: correct keyword; from Yatao Su via GHPR509 + upstream: mux: fix incorrect return value check in local forward - OpenBSD-Commit-ID: 81c778c76dea7ef407603caa157eb0c381c52ad2 + cancellation + + channel_cancel_lport_listener() returns 1 on success and 0 on failure. + The previous code incorrectly checked for `== -1`, a value the function + never returns, so failure was not detected and the "port not found" + error message was never shown when cancelling dynamic or local port + forwards. + + From: Boris Tonofa + + OpenBSD-Commit-ID: 3e9d2252a4d0bd318d4f25e2b518afb44acea170 -commit f2b78bb8f149d6b4d1f62c21aa1f06995dccf4ce -Author: djm@openbsd.org -Date: Mon Jul 8 03:04:34 2024 +0000 +commit 29cf521486bf97ab9de5b9b356f812107e0671bc +Author: Damien Miller +Date: Wed Jul 2 13:47:38 2025 +1000 - upstream: don't need return at end of void function + wrap some autoconf macros in AC_CACHE_CHECK - OpenBSD-Commit-ID: 42d322d37f13aa075ae7b1ad9eef591e20b89717 + This allows skipping/overriding the OSSH_CHECK_CFLAG_COMPILE and + OSSH_CHECK_CFLAG_LINK macros used to discover supported compiler + or linker flags. E.g. + + $ ./configure ossh_cv_cflag__fzero_call_used_regs_used=no + [...] + checking if cc supports compile flag -ftrapv and linking succeeds... yes + checking if cc supports compile flag -fzero-call-used-regs=used and linking succeeds... (cached) no + checking if cc supports compile flag -ftrivial-auto-var-init=zero... yes + + Patch from Colin Watson, ok dtucker@ -commit a395d37a813c0177cb5bfc4bebf5a52badb73cf0 -Author: djm@openbsd.org -Date: Thu Jul 4 22:53:59 2024 +0000 +commit b28e91aff80fd24341de8cb3c34dc454d6b75228 +Author: dtucker@openbsd.org +Date: Sun Jun 29 08:20:21 2025 +0000 - upstream: fix grammar: "a pattern lists" -> "one or more pattern + upstream: Add shebang path to askpass script. Required for exec on - lists" + some platforms (musl, probably others). - OpenBSD-Commit-ID: f3c844763398faa9800687e8ff6621225498202a + OpenBSD-Regress-ID: 35cdeed12ae701afcb812f800c04d817325cd22a -commit 8b664df75966e5aed8dabea00b8838303d3488b8 -Author: Darren Tucker -Date: Sun Jul 7 18:46:19 2024 +1000 +commit 83d3ffc0fc0f5e4473ab43f0d42a1cf9497ce0b5 +Author: dtucker@openbsd.org +Date: Sun Jun 29 05:35:00 2025 +0000 - Cast to sockaddr * in systemd interface. + upstream: Check dropbear server version for required features. - Fixes build with musl libx. bz#3707. + Dropbear added the '-D' flag in version 2025.87. We need that for the + dropbear-server test, so skip on older versions. + + OpenBSD-Regress-ID: 9db0b84edd54d3c00ab17db1dc6d62af4644c550 -commit 30c8c81da2169e78357d08dbb0ddd823b60e93bc +commit 0b17d564cfae82f2a52e9b4d588657da47ea4e43 Author: Darren Tucker -Date: Thu Jul 4 20:12:26 2024 +1000 - - Add 9.8 branch to ci-status page. - -commit ee6b9e661633fcefd29dba0c811cecbc4d027f6f -Author: Samuel Thibault -Date: Tue Mar 26 22:15:08 2024 +0100 +Date: Sun Jun 29 14:34:48 2025 +1000 - Fix detection of setres*id on GNU/Hurd + Encrypt temporary password we're setting. - Like Linux, proper _SOURCE macros need to be set to get declarations of - various standard functions, notably setres*id. Now that Debian is using - -Werror=implicit-function-declaration this is really required. While at - it, define other _SOURCE macros like on GNU/Linux, since GNU/Hurd uses - the same glibc. + Now that we want to actually use the random password for tests, we need + to correctly encrypt it, instead of just setting it to a random string + that's not the "locked" value. -commit fa41f6592ff1b6ead4a652ac75af31eabb05b912 -Author: Damien Miller -Date: Mon Jul 1 14:33:26 2024 +1000 +commit 700205bd861c25cc7564010cf63d984d8db5098a +Author: Darren Tucker +Date: Sun Jun 29 11:27:17 2025 +1000 - version numbers + Fix env again. -commit bfebb8a5130a792c5356bd06e1ddef72a0a0449f -Author: djm@openbsd.org -Date: Mon Jul 1 04:31:59 2024 +0000 +commit 223a1beac7b7be9252f69055781c9c15f4d8a607 +Author: Darren Tucker +Date: Sun Jun 29 11:24:42 2025 +1000 - upstream: openssh-9.8 - - OpenBSD-Commit-ID: 5f8b89e38a4c5f7c6d52ffa19f796d49f36fab19 + Move env again. -commit 146c420d29d055cc75c8606327a1cf8439fe3a08 -Author: djm@openbsd.org -Date: Mon Jul 1 04:31:17 2024 +0000 +commit d32614b448528ac08a65caac323a34b4f559a204 +Author: Darren Tucker +Date: Sun Jun 29 11:22:00 2025 +1000 - upstream: when sending ObscureKeystrokeTiming chaff packets, we - - can't rely on channel_did_enqueue to tell that there is data to send. This - flag indicates that the channels code enqueued a packet on _this_ ppoll() - iteration, not that data was enqueued in _any_ ppoll() iteration in the - timeslice. ok markus@ - - OpenBSD-Commit-ID: 009b74fd2769b36b5284a0188ade182f00564136 + Move env to where it (hopefully) belongs. -commit 637e4dfea4ed81264e264b6200172ce319c64ead -Author: djm@openbsd.org -Date: Mon Jul 1 03:10:19 2024 +0000 +commit 8a9384de483b8fb69a800e0347273686a5715fc3 +Author: Darren Tucker +Date: Sun Jun 29 11:14:18 2025 +1000 - upstream: use "lcd" to change directory before "lls" rather then "cd", - - since the directory we're trying to list is local. Spotted by Corinna - Vinschen - - OpenBSD-Regress-ID: 821feca4a4bebe491944e624c8f7f2990b891415 + Enable password tests on Github ephemeral VMs. -commit c8cfe258cee0b8466ea84597bf15e1fcff3bc328 -Author: djm@openbsd.org -Date: Thu Jun 27 23:01:15 2024 +0000 +commit bcfe7340d9b622ecd978c87dbf885c8b5a503ca2 +Author: dtucker@openbsd.org +Date: Sat Jun 28 13:34:08 2025 +0000 - upstream: delete obsolete comment + upstream: Add simple regression test for dropbear as a server. - OpenBSD-Commit-ID: 5fb04f298ed155053f3fbfdf0c6fe7cdf84bbfa2 + OpenBSD-Regress-ID: 7abe1f6607d0cd49839918aade8f135d2462d389 -commit 94b9d37100f6fa536aaa1d1a0e4926fe44fbf04d -Author: djm@openbsd.org -Date: Thu Jun 27 22:36:44 2024 +0000 +commit 838d5ec4b12fb519ed9db76e5beccf11b7ee212f +Author: dtucker@openbsd.org +Date: Tue Jun 24 12:28:23 2025 +0000 - upstream: retire unused API + upstream: Add simple test for password auth. Requires some setup - OpenBSD-Commit-ID: 3e30d7b0615e2707f6bbe70f61b1c2f72f78161b - -commit 268c3a7f5783e731ed60f4e28da66ee3743581d3 -Author: jmc@openbsd.org -Date: Thu Jun 27 21:02:16 2024 +0000 - - upstream: ssl(8) no longer contains a HISTORY section; + so does not run by default. - OpenBSD-Commit-ID: 83b7ff34433d79595e9c2a5d2a561a6660251245 + OpenBSD-Regress-ID: d5ded47a266b031fc91f99882f07161ab6d1bb70 -commit 12b6cc09ce6c430681f03af2a8069e37a664690b +commit 57fb460165ae3b2d591f2468d7fe13cc1abda26d Author: djm@openbsd.org -Date: Wed Jun 26 23:47:46 2024 +0000 - - upstream: move child process waitpid() loop out of SIGCHLD handler; - - ok deraadt - - OpenBSD-Commit-ID: 65815a39564e431414aed7c5ace8076f4e9ca741 +Date: Tue Jun 17 01:24:32 2025 +0000 -commit d6bcd13297c2ab8b528df5a6898f994734849031 -Author: deraadt@openbsd.org -Date: Wed Jun 26 23:16:52 2024 +0000 + upstream: add RCS ID + + OpenBSD-Regress-ID: 6e30094e3bf0a1c65efb75c67a87093304a3e619 - upstream: Instead of using possibly complex ssh_signal(), write all +commit 688fa02728f2efbf18388bc1a8e94e7ba7ee4f11 +Author: djm@openbsd.org +Date: Tue Jun 24 09:22:03 2025 +0000 + + upstream: make "Match !final" not trigger a 2nd pass ssh_config - the parts of the grace_alarm_handler() using the exact things allowed by the - signal-safe rules. This is a good rule of thumb: Handlers should be written - to either set a global volatile sig_atomic_t inspected from outside, and/or - directly perform only safe operations listed in our sigaction(2) manual page. - ok djm markus + parsing pass (unless hostname canonicalisation or a separate "Match final" + does). bz3843 - OpenBSD-Commit-ID: 14168ae8368aab76e4ed79e17a667cb46f404ecd + ok dtucker@ + + OpenBSD-Commit-ID: ce82b6034828888f0f3f1c812e08f5e87400d802 -commit b8793e2b0851f7d71b97554fa5260b23796d6277 -Author: deraadt@openbsd.org -Date: Wed Jun 26 23:14:14 2024 +0000 +commit 5ba8391d697740a838fd8811434f707f0e079baa +Author: djm@openbsd.org +Date: Thu Jun 19 05:49:05 2025 +0000 - upstream: save_errno wrappers inside two small signal handlers that + upstream: better debug diagnostics when loading keys. Will now list - perform system calls, for systems with libc that do perform libc sigtramps. - ok djm markus + key fingerprint and algorithm (not just algorithm number) as well as making + it explicit which keys didn't load. - OpenBSD-Commit-ID: 7749b56419a7c9dcfe4c6c04811e429813346c62 + OpenBSD-Commit-ID: ee3e77a0271ab502e653922c6d161b1e091f8fee -commit f23e9332c4c8df37465c4a4f38275ea98980ed7e -Author: jmc@openbsd.org -Date: Mon Jun 24 06:59:39 2024 +0000 +commit b360f3a675e24b0dbb2ec30d985e3b6756996c0d +Author: djm@openbsd.org +Date: Tue Jun 17 01:20:17 2025 +0000 - upstream: - uppercase start of sentence - correct sentence grammar - - ok djm + upstream: whitespace - OpenBSD-Commit-ID: 1ec4b0fdb633a43667f2c8fff1d600bd647dde25 + OpenBSD-Commit-ID: 6e96814bcf70d0edbb0749ec61cc4fd8707f286d -commit 1839e3eb71a759aa795602c1e4196300f4ac2615 +commit ad38ec5f1b6768944d64ed7709da8706538b5509 Author: djm@openbsd.org -Date: Mon Jun 24 04:05:11 2024 +0000 +Date: Tue Jun 17 01:19:27 2025 +0000 - upstream: mention SshdSessionPath option + upstream: fix leak on error path; Coverity CID 481976 - OpenBSD-Commit-ID: c29734d36c21003973b15c1c9965c35f36cef30c + OpenBSD-Commit-ID: 963dba2c804e2fd8efea2256092899874d0dbc7b -commit 603193e32aef5db7d60c58066d5de89806e79312 +commit 5f761cdb2331a12318bde24db5ca84ee144a51d1 Author: Darren Tucker -Date: Thu Jun 20 18:45:14 2024 +1000 +Date: Tue Jun 17 21:46:37 2025 +1000 - Rerun upstream tests on .sh file changes too. + Update obsd tests to use current images. -commit dbbf9337c19381786a8e5a8a49152fe6b80c780d +commit 1e8347e3543a415067ccc556aefea97656ecafb7 +Author: Damien Miller +Date: Tue Jun 17 09:48:47 2025 +1000 + + add sshd-auth to RPM spec files + +commit dd800444943bd64913507f6005586136d49f63db Author: dtucker@openbsd.org -Date: Thu Jun 20 08:23:18 2024 +0000 +Date: Mon Jun 16 09:09:42 2025 +0000 - upstream: Work around dbclient cipher/mac query bug. + upstream: Limit each moduli size to a max of 100 entries. - Unlike earlier versions, recent Dropbear (at least v2024.85) requires - a host arg when querying supported ciphers and macs via "-c/-m - help". Earlier versions accept but do not require it, so always - provide it. If these queries fail, skip the test with a warning. + OpenBSD-Commit-ID: 747219d54565030ff7c45298b9f5e971801f6cb2 + +commit 05f7bf46d1e2c101e9cbdd3df2ccee484bed969f +Author: dtucker@openbsd.org +Date: Mon Jun 16 09:07:08 2025 +0000 + + upstream: Now that ssh-keygen defaults to the maximum memory for - OpenBSD-Regress-ID: 98eb863a3f0363416922efb273885e6b3c7f68d4 + moduli generation we no longer need to run it twice to get enough. Use mkdir + -p instead of a conditional, which allows "make -jN" to work without error. + + OpenBSD-Commit-ID: c2eb57285424f819f9520fa33e0d6d3c4a361a5e -commit 8de2c8cebc46bbdb94b7a2c120fcadfb66a3cccc +commit df3f903d616763a105570610a616dacf0f83438e Author: dtucker@openbsd.org -Date: Thu Jun 20 08:18:34 2024 +0000 +Date: Mon Jun 16 09:02:19 2025 +0000 - upstream: Remove dropbear key types not supported + upstream: Fix overflow check in sshbuf_dup_string. It's already - by current OpenSSH. Allows subsequent test runs to work if OpenSSH is - rebuilt w/out OpenSSL. + constrained by SSHBUF_SIZE_MAX, but still worth fixing the check. Patch from + afonot via github PR#573, with & ok djm@ - OpenBSD-Regress-ID: e0129eb2b1d31771105903a8055216fbba20a770 + OpenBSD-Commit-ID: 438888498e66472fc6a48133196d6538d27bff18 -commit e9b6471c59b21e5d9ef1b3832d4bf727338add85 -Author: djm@openbsd.org -Date: Thu Jun 20 00:18:05 2024 +0000 +commit 80916d0d3794e2f92dd6998d7c45daba484e4f18 +Author: dtucker@openbsd.org +Date: Mon Jun 16 08:53:04 2025 +0000 - upstream: stricter check for overfull tables in penalty record path + upstream: Plug mem leak. Patch from afonot via github PR#574, ok djm@ - OpenBSD-Commit-ID: 7df01e648a0723418c554e64a9f2b6d38db060a6 + OpenBSD-Commit-ID: 65619f14ef206028ce39bc31f704b832a0609688 -commit d9336d344eb2a1e898c5e66147b3f108c7214694 -Author: djm@openbsd.org -Date: Wed Jun 19 23:24:47 2024 +0000 +commit bd1bd7e8296aa51a4b3958cef2fbb17894ba94e9 +Author: dtucker@openbsd.org +Date: Mon Jun 16 08:49:27 2025 +0000 - upstream: put back reaping of preauth child process when writes + upstream: Save return value from sshbuf_len instead of calling it - from the monitor fail. Not sure how this got lost in the avalanche of - patches. + multiple times. Fixes Coverity CID 470521. - OpenBSD-Commit-ID: eb7eb36371e1ac01050b32b70fb2b3e5d98e72f5 + OpenBSD-Regress-ID: 356b8b43c8a232deaf445c1ff7526577b177a8e9 -commit 579d9adb70ec0206a788eb5c63804c31a67e9310 -Author: naddy@openbsd.org -Date: Mon Jun 17 13:50:18 2024 +0000 +commit 2827b6ac304ded8f99e8fbc12e7299133fadb2c2 +Author: dtucker@openbsd.org +Date: Fri Jun 13 07:35:14 2025 +0000 - upstream: remove one more mention of DSA + upstream: Plug leak. Coverity CID 405058. - OpenBSD-Commit-ID: 8515f55a15f02836ba657df341415f63c60526ca + OpenBSD-Regress-ID: 7fb2fce68d2cb063cdb94d5d66f84fa3a2902792 -commit 7089b5f8436ef0b8d3d3ad9ce01045fb9e7aab15 -Author: Darren Tucker -Date: Wed Jun 19 23:09:05 2024 +1000 +commit 9cdc72b829e9f0e24dedc533cbe87291d8a88c9e +Author: dtucker@openbsd.org +Date: Fri Jun 13 07:23:07 2025 +0000 - Move -f to the place needed to restart sshd. + upstream: Remove dead code flagged by Coverity CID 307783. ok djm@ + + OpenBSD-Regress-ID: e579f5ec2fd2eb2fe2bad654d16f2ba655a3e035 -commit d5f83cfd852b14a25f347f082ab539a9454702ad -Author: Darren Tucker -Date: Wed Jun 19 21:04:01 2024 +1000 +commit 930a45ee759728c8ba711c45a2a985b8191bd297 +Author: dtucker@openbsd.org +Date: Thu Jun 12 10:09:39 2025 +0000 - Need to supply "-f" to restart sshd. + upstream: Set user, host and path to NULL immediately before calling + + parse_user_host_path in tests. This ensures that we don't accidentally use + the previous value if the function under test doesn't set them Also fixes + Coverity CIDs 405056 405065 405066. + + OpenBSD-Regress-ID: 43678ff59001712f32214fe303b1c21c163c2960 -commit fad34b4ca25c0ef31e5aa841d461b6f21da5b8c1 +commit 2314d87f9b8b430532111fd6e5e8df0cf9068c9c Author: dtucker@openbsd.org -Date: Wed Jun 19 10:15:51 2024 +0000 +Date: Thu Jun 12 09:26:57 2025 +0000 - upstream: Provide defaults for ciphers and macs + upstream: Plug mem leak on error path here too. - if querying for them fails since on some versions of Dropbear (at least - v2024.85) "-m help" doesn't seem to work. Enable all supported pubkey - algorithms in the server. + Coverity CID 307781. - OpenBSD-Regress-ID: 4f95556a49ee9f621789f25217c367a33d2745ca + OpenBSD-Regress-ID: 18e053d9b661fbb4227d3db03172077c1216bb2e -commit 5521060e35ada9f957cecdddc06d0524e75409ef +commit 567ef4e7ddc5c1e7a461560963a1dc759669821d Author: dtucker@openbsd.org -Date: Wed Jun 19 10:10:46 2024 +0000 +Date: Thu Jun 12 09:19:43 2025 +0000 - upstream: Use ed25519 keys for kex tests + upstream: Plug mem leak on error path. - since that's supported by OpenSSH even when built without OpenSSL. - Only test diffie-hellman kex if OpenSSH is compiled with support for it. + Coverity CID 307776. - OpenBSD-Regress-ID: a5d09ef9bbd171f9e4ec73ed0d9eeb49a8878e97 + OpenBSD-Regress-ID: c44246690973e1b8643e51079a2faa7ace26490c -commit dbd3b833f6e3815e58f2dc6e14f61a51bcd4d6bd +commit 5d415897ac04e237f1fa73b9dcb9ba8fb3ac812b Author: dtucker@openbsd.org -Date: Wed Jun 19 10:08:34 2024 +0000 +Date: Wed Jun 11 13:27:11 2025 +0000 - upstream: Rework dropbear key setup + upstream: Remove dead code ternary. We always report at least - to always generate ed25519 keys, other types only if OpenSSH has support - for the corresponding key type. + KB/s, so B/s is never used. Coverity CID 291809, ok djm@ - OpenBSD-Regress-ID: 8f91f12604cddb9f8d93aa34f3f93a3f6074395d + OpenBSD-Commit-ID: a67c5bcc9e19c8965bfeace0e337b13660efa058 -commit d6218504e11ae9148adf410fc69b0710a052be36 -Author: Darren Tucker -Date: Wed Jun 19 20:20:24 2024 +1000 +commit 4b3d27032ba88dd089b721f3bbe3e4a8d23b4ae1 +Author: dtucker@openbsd.org +Date: Wed Jun 11 13:24:05 2025 +0000 - Restart sshd after installing it for testing. + upstream: Improve termination condition of while loop to compare - When installing an sshd built without OpenSSL the mismatch between - the running sshd and newly installed sshd-session will cause the - remainder of the test to fail. + size_t's. Assuming read() does what it's supposed to this shouldn't matter, + but should be more robust. Flagged by Coverity CID 470514, ok djm@ + + OpenBSD-Commit-ID: d7b5ad60feb797b3464964b9ea67fd78fb9d6cc6 -commit 786a4465b6bb702daf4fb17b7c3bcb42b52f0b46 +commit 5530e5f83b3cd3425ea3dbab02da15140befdd91 Author: Darren Tucker -Date: Tue Jun 18 19:59:59 2024 +1000 +Date: Tue Jun 10 18:40:56 2025 +1000 - Remove macos-11 runner. + Replace Windows 2019 runners with 2025 ones. - Github is retiring them soon. + The windows-2019 runners are being decomissioned. -commit df1c72a55edbebac14363b57de66ac6a147ecc67 -Author: Damien Miller -Date: Wed Jun 19 09:34:34 2024 +1000 +commit a22ff3c6f11edd00c19981f9cb85d3b25d305a56 +Author: Darren Tucker +Date: Wed Jun 4 18:33:52 2025 +1000 - PAMServiceName may appear in a Match block + Disable _FORTIFY_SOURCE during snprintf test. + + Prevents mistakenly detecting snprintf as broken on FreeBSD 15 with + _FORTIFY_SOURCE enabled. bz#3809, patch from jlduran at gmail.com -commit de1c2e70e5a5dc3c8d2fe04b24cc93d8ef6930e7 +commit 203bb886797677aa5d61b57be83cfdc1b634bc9c Author: dtucker@openbsd.org -Date: Tue Jun 18 08:11:48 2024 +0000 +Date: Mon Jun 2 14:09:34 2025 +0000 - upstream: Re-enable ssh-dss tests + upstream: Fix x11_channel_used_recently() to return true when channel - ... if ssh is compiled with DSA support + has been used within the last second, instead of more than a second ago. + Should fix ~5s delay on X client startup when ObscureKeystrokeTiming is + enabled. bz#3820, ok (& sigh) djm@ - OpenBSD-Regress-ID: bbfaf8c17f2b50a2d46ac35cb97af99b990c990d + OpenBSD-Commit-ID: b741011e81fb3e3d42711d9bd3ed8a959924dee4 -commit dabc2c7cf3c141e8e5d5a1a60d6c1d2d2422cf43 -Author: anton@openbsd.org -Date: Tue Jun 18 06:14:27 2024 +0000 +commit dc6c134b48ba4bcfadedcea17b4eddac329601d9 +Author: dtucker@openbsd.org +Date: Thu May 29 13:27:27 2025 +0000 - upstream: Stop using DSA in dropbear interop tests. + upstream: When there's more than one x11 channel in use, return - OpenBSD-Regress-ID: abfd4457d99d8cc1417fd22ca2c570270f74c1cf - -commit 761438012710169445acc179e3870c53c862bda0 -Author: Damien Miller -Date: Tue Jun 18 12:29:45 2024 +1000 - - missed a bit of DSA in the fuzzer + lastused of most recently used x11 channel instead of the last one found. ok + djm@ + + OpenBSD-Commit-ID: 94a72bf988d40a5bae2e38608f4e117f712569fe -commit 3f9cc47da588e8de520720e59f98438043fdaf93 -Author: Damien Miller -Date: Tue Jun 18 09:35:53 2024 +1000 +commit 73ef0563a59f90324f8426c017f38e20341b555f +Author: djm@openbsd.org +Date: Sat May 24 11:41:51 2025 +0000 - DSA support is disabled, so remove from fuzzers + upstream: replace xmalloc+memset(0) with xcalloc(); from AZero13 via + + GHPR417 + + OpenBSD-Commit-ID: 921079436a4900325d22bd3b6a90c8d0d54f62f8 -commit 00eb95957dea5484b2c7c043f7d2bbc87301bef2 +commit 3a61f5ed66231881bee432c7e7c6add066c086af Author: djm@openbsd.org -Date: Mon Jun 17 08:30:29 2024 +0000 +Date: Sat May 24 09:46:16 2025 +0000 - upstream: disable the DSA signature algorithm by default; ok + upstream: fix punctuation around host key fingerprints to make them - markus@ + easier to copy and paste. - (yes, I know this expands to "the Digitial Signature Algorithm - signature algorithm) + Patch from Till Maas via GHPR556; ok dtucker@ - OpenBSD-Commit-ID: 961ef594e46dd2dcade8dd5721fa565cee79ffed + OpenBSD-Commit-ID: c0100182a30b6925c8cdb2225b18140264594b7b -commit 5603befe11c9464ea26fe77cbacc95a7cc0b1ea7 -Author: djm@openbsd.org -Date: Mon Jun 17 08:28:31 2024 +0000 +commit b12d4ab1e16f57c6c348b483b1dbdd4530aaaddd +Author: dtucker@openbsd.org +Date: Sat May 24 08:13:29 2025 +0000 - upstream: promote connection-closed messages from verbose to info + upstream: Replace strncmp + byte count with strprefix in Penalty - log level; they could be the only record of the connection terminating if the - client doesn't send a SSH2_MSG_DISCONNECT message. ok dtucker@ + config parsing. ok kn@, djm@ - OpenBSD-Commit-ID: 0c8bfaf5e9fdff945cee09ac21e641f6c5d65d3c + OpenBSD-Commit-ID: 34a41bb1b9ba37fb6c7eb29a7ea909547bf02a5a -commit b00331402fe5c60d577f3ffcc35e49286cdc6b47 -Author: Damien Miller -Date: Mon Jun 17 17:02:18 2024 +1000 +commit a356d978e30dd9870c0b3a7d8edca535b0cd2809 +Author: dtucker@openbsd.org +Date: Sat May 24 08:09:32 2025 +0000 - propagate PAM crashes to PerSourcePenalties + upstream: Make the display number check relative to - If the PAM subprocess crashes, exit with a crash status that will be - picked up by the sshd(8) listener process where it can be used by - PerSourcePenalties to block the client. This is similar handling to - the privsep preauth process. + X11DisplayOffset. + + This will allows people to use X11DisplayOffset to configure much higher + port ranges if they really want, while not changing the default behaviour. + Patch from Roman Gubarev via github PR#559, ok djm@ + + OpenBSD-Commit-ID: e0926af5dc0c11e364452b624c3ad0cda88550b5 -commit 1c207f456ace38987deda047758d13fbf857f948 -Author: Damien Miller -Date: Mon Jun 17 15:06:01 2024 +1000 +commit e18983d03ab969e2f12485d5c0ee61e6d745a649 +Author: Darren Tucker +Date: Sat May 24 17:20:57 2025 +1000 - minix doesn't have loopback, so skip penalty tests + Remove progressmeter.o from libssh.a. - pointed out by dtucker@ + It's now explicitly included by the binaries that need it (scp & sftp). + bz#3810, patch from jlduran at gmail.com -commit 48443d202eaec52d4d39defdd709a4499a7140c6 -Author: djm@openbsd.org -Date: Sun Jun 16 11:54:49 2024 +0000 +commit f8967045ad9d588bc11426642070bf8549065e62 +Author: dtucker@openbsd.org +Date: Sat May 24 06:50:28 2025 +0000 - upstream: same treatment for this test + upstream: Null out keys between test runs. - OpenBSD-Regress-ID: d0cc9efca7833e673ea7b0cb3a679a3acee8d4c7 + BENCH_START and BENCH_FINISH are actually a while() loop in disguise, + so if sshkey_generate does not reset the key pointer on failure the test + may incorrectly pass. It also confuses Coverity (CID 551234). + + OpenBSD-Regress-ID: bf4d32079fc6df6dce1f26c2025f4ed492f13936 -commit 45562a95ea11d328c22d97bf39401cd29684fb1f +commit a26091ecdb2a3d72b77baf3c253e676a3c835a24 Author: djm@openbsd.org -Date: Sun Jun 16 08:18:06 2024 +0000 +Date: Sat May 24 04:41:12 2025 +0000 - upstream: penalty test is still a bit racy + upstream: add some verbosity - OpenBSD-Regress-ID: 90c9ac224db454637baf1ebee5857e007321e824 + OpenBSD-Regress-ID: 11c86cda4435b5f9ab6172c4742b95899666c977 -commit 8d0f7eb147ef72d18acb16c0b18672d44941a8ca +commit 484563ec70e30472ab4484d49bca9a83771d785c Author: djm@openbsd.org -Date: Sat Jun 15 03:59:10 2024 +0000 +Date: Sat May 24 04:41:03 2025 +0000 - upstream: crank up penalty timeouts so this should work on even the - - slowest of test builders + upstream: use start_ssh_agent() to ensure we get logging - OpenBSD-Regress-ID: 70bda39c83e3fc9d0f3c1fad4542ed33e173d468 - -commit 93c75471a1202ab3e29db6938648d4e2602c0475 -Author: jmc@openbsd.org -Date: Fri Jun 14 05:20:34 2024 +0000 - - upstream: sort -q in the options list; + add some verbosity - OpenBSD-Commit-ID: 6839b38378f38f754de638a5e988c13b4164cc7c + OpenBSD-Regress-ID: a89bf64696b9fb1b91be318e6b8940c9ab21c616 -commit dd7807bbe80a93ffb4616f2bd5cf83ad5a5595fb +commit e3c58113ebb3397b252ff26e0e94f726b7db7a8a Author: djm@openbsd.org -Date: Fri Jun 14 05:01:22 2024 +0000 +Date: Sat May 24 04:40:37 2025 +0000 - upstream: clarify KEXAlgorithms supported vs available. Inspired by + upstream: add a start_ssh_agent() function that sets up an agent - bz3701 from Colin Watson. + with logging - OpenBSD-Commit-ID: e698e69bea19bd52971d253f2b1094490c4701f7 + OpenBSD-Regress-ID: 7f9f30f9c64acbd4b418a5e1a19140cc988071a8 -commit d172ad56df85b68316dbadbedad16761a1265874 -Author: djm@openbsd.org -Date: Fri Jun 14 05:00:42 2024 +0000 +commit 3de011ef7a761751afe28ac7ef97fe330d784595 +Author: dtucker@openbsd.org +Date: Sat May 24 06:43:37 2025 +0000 - upstream: ssh-keyscan -q man bits + upstream: Plug leak of startup_pollfd in debug and child paths. - OpenBSD-Commit-ID: ba28d0e1ac609a4c99c453e57e86560c79079db1 + Coverity CID 405024, ok djm@ + + OpenBSD-Commit-ID: db46047229253e9c4470c8bbf5f82706ac021377 -commit 092e4ff9ccaacbe035f286feb1b56ed499604743 -Author: Damien Miller -Date: Fri Jun 14 14:46:35 2024 +1000 +commit d0245389bc55f16082cadd0a39dda5af1c415dfa +Author: Darren Tucker +Date: Sat May 24 17:11:38 2025 +1000 - skip penalty-expire test in valgrind test env + ssh-keygen changes were fixup'ed into single commit. -commit 2866ad08a9c50d7b67ce9424ca990532b806a21a -Author: djm@openbsd.org -Date: Fri Jun 14 04:43:11 2024 +0000 +commit 140bae1df2b7246bb43439d039bf994159973585 +Author: Marco Trevisan (Treviño) +Date: Mon Sep 30 13:14:11 2024 +0200 - upstream: split the PerSourcePenalties test in two: one tests penalty - - enforcement but not penalty expiry, the other tests penalty expiry. + auth-pam: Check the user didn't change during PAM transaction - This lets us disable the expiry testing in certain CI test environments. + PAM modules can change the user during their execution, in such case ssh + would still use the user that has been provided giving potentially + access to another user with the credentials of another one. - OpenBSD-Regress-ID: f56811064f3e3cb52ee73a206b8c2a06af1c8791 + So prevent this to happen, by ensuring that the final PAM user is + matching the one that initiated the transaction. -commit b2c64bc170d75823622a37cab3ca1804ca87ad16 -Author: Damien Miller -Date: Fri Jun 14 14:19:23 2024 +1000 +commit 216824172724a50a4a75439fb2b4b8edccf5b733 +Author: dtucker@openbsd.org +Date: Sat May 24 03:37:40 2025 +0000 - add a sshd_config PamServiceName option + upstream: Remove ssh-keygen's moduli screen -Omemory option. - Allows selecting which PAM service name to use when UsePAM is - enabled. Defaults to "sshd" unless overridden at compile time - by defining SSHD_PAM_SERVICE. + This vaguely made sense 20 years ago, but these days you'd be hard + pressed to *find* a machine small enough to not support the maximum + (127MB), and no one is screening moduli on such machines anyway, + so just use the max. This also fixes Coverity CID 470522 by deleting + code in question. "kill it with fire" djm@. - bz2102, ok dtucker@ + OpenBSD-Commit-ID: 39036aa406a99f0a91923aa3a96afff1205558e6 -commit 9f032a4dd17bf0ae6066223d82aa5e784285d987 -Author: djm@openbsd.org -Date: Fri Jun 14 00:26:12 2024 +0000 +commit f5cd14e81fa29b4924959cb2e1f9c206aae2d502 +Author: dtucker@openbsd.org +Date: Sat May 24 02:33:33 2025 +0000 - upstream: don't redirect stderr for ssh-keyscan we expect to succeed + upstream: Fix compile error on 32bit platforms. - OpenBSD-Regress-ID: 8878b8eb4e070ed2e343166d3eb86db4a08a216c + Spotted by & ok tb@ + + OpenBSD-Commit-ID: cbcf518247886f3c7518fc54cb3bd911ffc69db7 -commit 1e84d0cf40e94ae3a77d6a7ca8c036d8e3d55a40 -Author: djm@openbsd.org -Date: Fri Jun 14 00:25:25 2024 +0000 +commit eccc15014fe146e8590568e6737a3097bfac3415 +Author: dtucker@openbsd.org +Date: Sat May 24 02:01:28 2025 +0000 - upstream: make host/banner comments go to stderr instead of stdout, + upstream: Use pointer from strprefix in error message, + + missed in previous. - so they are useful as comments without extra shell redirection and so they - don't clutter actual errors on stderr. + OpenBSD-Commit-ID: d2cdec6cf0fcd4b0ee25e4e3fad8bc8cf0ee657d + +commit 91903511d0597c3bea218167f9ca5a176fa0dc20 +Author: dtucker@openbsd.org +Date: Fri May 23 12:52:45 2025 +0000 + + upstream: Replace strncmp and strncasecmp with hand-counting bytes - Add a -q flag to shut them up. + with strprefix. nits lucas@, ok lucas@ djm@ - ok dtucker@ + OpenBSD-Commit-ID: f0888807f151ea2bdaf6fed36303ae81f259d1d4 + +commit 0c64d69e4e24a3ab06f7922ef389e7399c4dfb88 +Author: dtucker@openbsd.org +Date: Fri May 23 11:54:50 2025 +0000 + + upstream: Include stdint.h for UINT32_MAX. - OpenBSD-Commit-ID: bec813de56a71adb5c1a76adcf49621130d24264 + OpenBSD-Commit-ID: edc29ed67e8bd03bac729d9b4849066d1d3a8cb9 -commit 3e806d011855d6bd648ec95b9df630ebbd11c3bf -Author: naddy@openbsd.org -Date: Thu Jun 13 15:06:33 2024 +0000 +commit 3e11478f585408888defa56fa47e8dc6567378d0 +Author: dtucker@openbsd.org +Date: Fri May 23 11:25:35 2025 +0000 - upstream: separate keywords with comma + upstream: Ensure args to nh_update() fit within uint32, which it - OpenBSD-Commit-ID: d65a99666202a8188c4991c18d14374a229f7be5 + should always anyway. Placates Coverity CID 470520. While there, fix the + upstream URL. ok djm@ + + OpenBSD-Commit-ID: 2478e89fde089a49fa02f9faf6287d35959c9f92 -commit abfd1f7a3cbd0a92581a0febba254b2f6649c0d9 -Author: djm@openbsd.org -Date: Fri Jun 14 00:23:55 2024 +0000 +commit f097d7bd07da4634c1a723d1dc4fcf56e7d0e147 +Author: dtucker@openbsd.org +Date: Fri May 23 09:26:25 2025 +0000 - upstream: specify an algorithm for ssh-keyscan, otherwise it will make + upstream: Don't leak the args list. Coverity CIDs 481569 & 481570, - multiple attempts simultaneously and confuse the test + ok job@ tb@. - OpenBSD-Regress-ID: 6e910f3315c4345053db1bf5cbf61826b194d0b9 + OpenBSD-Commit-ID: becabcd00513d13d1435b68b7ccffa7151b72393 -commit a8fbe2f7d0d96d299ee8e69769e3b51067978748 -Author: Damien Miller -Date: Thu Jun 13 16:41:29 2024 +1000 +commit a4ea7f6042f25b41061a83445016a1ea4f470f7b +Author: dtucker@openbsd.org +Date: Fri May 23 08:40:13 2025 +0000 - sshd: don't use argv[0] as PAM service name + upstream: Explictly set LC_ALL=C on each sort invocation. - sshd would implicitly use argv[0] as the PAM service name to - allow people to select different PAM service names by making - differently-named copies/links to the sshd binary. + Remove it from sshd_config (where it could be overridden by shell startup + scripts, eg on macos-15) causing random test failures. with & ok djm@ - Splitting sshd into sshd/sshd-session broke this, as the process - that starts PAM is always sshd-session and the user has no control - over this. + OpenBSD-Regress-ID: ad0a6678964784096e9a9e6d15ead36beed92f18 + +commit 7674c03caed80cb3565d14690c92068a14051967 +Author: Darren Tucker +Date: Fri May 23 16:39:18 2025 +1000 + + Allow setting LTESTS in repo variables. + +commit d8b5bd36078e5b6d78da4633f0cc9b90ffda8b50 +Author: Darren Tucker +Date: Fri May 23 16:26:20 2025 +1000 + + Rename debugging variable RUN_ONLY_TEST. - Hardcode "sshd" as the default PAM service name unless/until we - figure out a better way. Should unbreak OSX integration tests. + to RUN_ONLY_TARGET_CONFIG to make it more obvious what it matches. -commit bf204bd05c3ae650f87e2b96527688579f59774c -Author: Damien Miller -Date: Thu Jun 13 15:00:28 2024 +1000 +commit a79a2c1190bd3124da21d9e1582dd94877c7f972 +Author: Darren Tucker +Date: Fri May 23 16:11:48 2025 +1000 - prepare for checking in autogenerated files + chown regress logs before uploading. + +commit 24889a33071086b6f1f62568b0c2bd0a4955ac49 +Author: dtucker@openbsd.org +Date: Fri May 23 01:14:35 2025 +0000 + + upstream: Import regenerated moduli. - We plan to check in automatically generated files (config.h.in, etc) on - release branches. These files are normally ignored by .gitignore, but - this shuffles the contents of this file to make it easy to un-ignore - them. + OpenBSD-Commit-ID: 07e29dc891e29b31e03e2e5493658b4a9ac19431 -commit 425f79a837489904c343b349ef00e09aeaa4e752 -Author: Damien Miller -Date: Thu Jun 13 14:41:33 2024 +1000 +commit 4b8bee62d72ffb3c419c9ead6c9fb1a586283868 +Author: deraadt@openbsd.org +Date: Fri May 23 00:40:45 2025 +0000 - typo in comment + upstream: use "const char * const" for malloc_options here also + + OpenBSD-Commit-ID: 869715b9c7e1dd5b85efd07814e7e53f0286eea2 -commit afe10313c1fa8d478af399ee7d54c8f85503013b -Author: Damien Miller -Date: Thu Jun 13 14:35:25 2024 +1000 +commit 6629eee21ca9d0a597a04dcac744a1ad882f912e +Author: dtucker@openbsd.org +Date: Thu May 22 12:14:19 2025 +0000 - fix PTY allocation on Cygwin, broken by sshd split + upstream: Adjust debug message to prevent (unsigned) integer overflow. - Cygwin doesn't support FD passing and so used to disable post-auth - privilege separation entirely because privsep requires PTY allocation - to happen in the privileged monitor process with the PTY file - descriptors being passed back to the unprivileged process. + Fixes Coverity CID 481110, ok djm@ - This brings back a minimal version of the previous special treatment - for Cygwin (and any other platform that sets DISABLE_FD_PASSING): - privilege separation remains enabled, but PTY allocation happens in - the post-auth user process rather than the monitor. + OpenBSD-Commit-ID: 26178bf3b812707fb498ea85d076cadd1f2eb686 + +commit 7acb70e05e9977ceca7b33df84ceaea337b1efef +Author: bluhm@openbsd.org +Date: Thu May 22 04:34:18 2025 +0000 + + upstream: Fix OpenBSD RCS ID typos. from Andrius V - This either requires PTY allocation to not need privilege to begin - with (this appears to be the case on Cygwin), or the post-auth - privsep process retain privilege (other platforms that set the - DISABLE_FD_PASSING option). + OpenBSD-Regress-ID: 5c03a2ef5323969fc4978f2eec4f1a25c48c572a + +commit 2b2a7a2a0d70023b439080bb2770ff36522dbea8 +Author: Darren Tucker +Date: Thu May 22 22:09:48 2025 +1000 + + Remove debug change accidentally commited. - Keeping privileges here is bad, but the non-Cygwin systems that set - DISABLE_FD_PASSING are so deeply legacy that this is likely to be the - least of their problems. + Fixes Coverity CID 481160. -commit f66d4df5749551380a8c4ae642347675a0b6a2e9 -Author: Damien Miller -Date: Thu Jun 13 11:33:09 2024 +1000 +commit 450a8a1df1577ddbe68fe8da1fb8514d3781ef32 +Author: Darren Tucker +Date: Thu May 22 21:16:37 2025 +1000 - delay lookup of privsep user until config loaded + Collect all of regress dir on failure. - sshd-session attempting to use options.kerberos_authentication to - decide whether it needed to lookup the privsep user before the - configuration was loaded. This caused it to get a placeholder value - that caused it always to try to lookup the privsep user, breaking at - least one test environment. + This may allow us to sort through its entrails and determine the cause + of some types of failures. -commit f1c42858b94f5d9b58867b34dce3afb39c6b56a8 +commit de25e739781c4c09d20abd410f50f0a6f192dc72 Author: Damien Miller -Date: Thu Jun 13 11:16:57 2024 +1000 +Date: Thu May 22 18:42:44 2025 +1000 - missing file for PerSourcePenalties regress test + minimal shims for fstatat(2)/unlinkat(2) in agent + + Add some very minimal and task-specific replacements for + fstatat(2) and unlinkat(2) in the ssh-agent socket cleanup + loop, for platforms that lack these functions. ok dtucker@ -commit 4de80ff4e6fab5a6bb0028e7d57c6c23d1485adb -Author: djm@openbsd.org -Date: Wed Jun 12 22:36:00 2024 +0000 +commit 6d192645a613aa814d51050b0458f37265b90d6c +Author: dtucker@openbsd.org +Date: Thu May 22 04:22:03 2025 +0000 - upstream: split PerSourcePenalties address tracking. Previously it + upstream: Output the current name for PermitRootLogin's - used one shared table and overflow policy for IPv4 and IPv6 addresses, now it - will use separate tables and optionally different overflow policies. + "prohibit-password" in sshd -T instead of its deprecated alias + "without-password". bz#3788, patch from cjwatson at debian.org. - This prevents misbehaviour from IPv6 addresses (which are vastly easier - to obtain many of) from affecting IPv4 connections and may allow for - stricter overflow policies. + OpenBSD-Commit-ID: 2d5df18d5ad33a9b6c7547ec78a8e6ea13813df9 + +commit 1ccf42378df202472e7254f37f7dabb2f5723955 +Author: dtucker@openbsd.org +Date: Thu May 22 03:53:46 2025 +0000 + + upstream: Copy arg to be passed to dirname(). - ok deraadt@ + POSIX allows dirname() to modify its args and return a pointer into it, + so this prevents an overlapping strlcpy. bz#3819, patch from cjwatson + at debian.org - OpenBSD-Commit-ID: 12637ed0aa4d5f1f3e702da42ea967cbd8bfdfd9 + OpenBSD-Commit-ID: c32e496e6a1618aba31c8b7a9d4e1376c5ea6aa1 -commit 06ab4c6931b0aaa4334db2faaa7e1069e76d0df6 -Author: jmc@openbsd.org -Date: Tue Jun 11 05:24:39 2024 +0000 +commit b5877b7b3e597f47578ade9dbe7e4332f112dfc4 +Author: dtucker@openbsd.org +Date: Thu May 22 03:41:10 2025 +0000 - upstream: do not mark up "(default: 20ms)"; + upstream: Add $OpenBSD$ marker for easier syncing. - OpenBSD-Commit-ID: 54151ecdecfa1b67dcdda4fd24826ef6e2148ad4 + OpenBSD-Commit-ID: 27ff3e1e2e6610d9981ebe43ae9b783236800035 -commit cfe243cd9fde148ed060637876e27bb55ac78be9 +commit 58d094c7cb974d7bd3ba6eb1059b186a2ac3dd55 Author: djm@openbsd.org -Date: Tue Jun 11 02:54:51 2024 +0000 +Date: Wed May 21 12:12:20 2025 +0000 - upstream: reap preauth net child if it hangs up during privsep message + upstream: Correct FILES section to mention new default path to - send, not just message receive + agent sockets. Spotted by / ok jmc@ - OpenBSD-Commit-ID: 02a093f4ab4f8f83f0cd1ea2bb35b9ca420448f0 + OpenBSD-Commit-ID: 91d736d78d71a4276c9cbb075b1462bbc3df55a6 -commit b0a711c00b9c64afd1c9d6fb538275c6604a2676 -Author: djm@openbsd.org -Date: Tue Jun 11 01:58:27 2024 +0000 +commit d1d5c8b9b8de8283618c18d0dafdec6a209911cc +Author: Darren Tucker +Date: Thu May 22 12:25:35 2025 +1000 - upstream: fix PIDFILE handling, broken for SUDO=doas in last commit - - here - - OpenBSD-Regress-ID: 96fec579af228f87a036e94801eb294af9074625 + Fix nc install some more. -commit 90fb801e2d9241be50a2a7ff79428386442a041f -Author: djm@openbsd.org -Date: Tue Jun 11 02:00:30 2024 +0000 +commit 49a2412ad23162e44be9e0b2cb12f6daf6b666d7 +Author: Darren Tucker +Date: Thu May 22 12:21:11 2025 +1000 - upstream: reap the pre-auth [net] child if it hangs up during privsep + Fix cvs up of nc. + +commit df22801b3f0ae245f825cf9c9dbb4543e41a7c5c +Author: Darren Tucker +Date: Thu May 22 11:34:04 2025 +1000 + + Install nc during upstream test. - message sending, not just receiving + This ensures that the installed nc matches the expectations of the + regress tests. + +commit e391c5289c2b687ff886cf780dc8fcb426e4d5d2 +Author: Darren Tucker +Date: Thu May 22 10:52:31 2025 +1000 + + Remove 9.7 branch from CI status page. - OpenBSD-Commit-ID: f7341605bf08c4c15830910446e6775323f2f8cb + It's been obsolete long enough that github no longer reports its + status. -commit ef878d58798f6688c7f4d4e417dc0c29023ea831 +commit b71773c20d566fa5dcaf9edf3139bdcb3f2c4bc2 +Author: Damien Miller +Date: Wed May 21 19:14:47 2025 +1000 + + pull a small netcat SOCKS4A fix from upstream + +commit 0adb2db25eff3fe1c90c55654387ae1e4e18a396 Author: djm@openbsd.org -Date: Tue Jun 11 01:23:25 2024 +0000 +Date: Wed May 21 08:41:52 2025 +0000 - upstream: a little more RB_TREE paranoia + upstream: test SOCKS4A; ok tb - OpenBSD-Commit-ID: 8dc2fd21eebd8830c4a4d25461ac4fe228e11156 + OpenBSD-Regress-ID: d880b75280295cd581a86e39bb0996d347f122d2 -commit fc4e96b2174d6a894d2033421699d091679baced +commit 5699f4e9553c6a228fd9dc578d99e3aa6451c014 Author: djm@openbsd.org -Date: Tue Jun 11 01:22:25 2024 +0000 +Date: Wed May 21 08:36:39 2025 +0000 - upstream: fix off-by-one comparison for PerSourcePenalty + upstream: remove log tarballing "it seemed like a good idea at the - OpenBSD-Commit-ID: af4f5d01c41ef870b23e55655bfbf73474a6c02b + time" - dtucker@ + + ensure that log files have correct perms when running under sudo/doas + + ok dtucker@ + + OpenBSD-Regress-ID: 20588c14b05de9519f85d638b374b66ae0678c89 -commit 82c836df4ff41145553cd7adb11c5b985aeaa06f +commit 0c14e6b69a20f20d602e0e72559ca3f4dbc797fb Author: djm@openbsd.org -Date: Tue Jun 11 01:21:41 2024 +0000 +Date: Wed May 21 06:44:24 2025 +0000 - upstream: move tree init before possible early return + upstream: use logit_f("...") instead of logit("func: ...") - OpenBSD-Commit-ID: 72e2c5b69f151c08a7c5bf5ad929b97a92c273df + OpenBSD-Commit-ID: c8d49eb39a9abff3cbcaeaf7df9d48468a5a0695 -commit a2300f015cc4939c4d9c564b58b74e71202dc978 +commit 1743589d038476f28dc4dfb1f69317649ae22ac5 Author: djm@openbsd.org -Date: Tue Jun 11 01:07:35 2024 +0000 +Date: Wed May 21 06:43:48 2025 +0000 - upstream: update to mention that PerSourcePenalties default to + upstream: function to make a sshbuf from a hex string; useful in - being enabled and document the default values for each parameter. + tests - OpenBSD-Commit-ID: b981288bddfb097aad269f62df4081c688ce0034 + also constify some arguments + + OpenBSD-Commit-ID: 00f9c25b256be0efd73f2d8268ff041bc45ffb2c -commit 41987efd356d3fc30139aeab4b09374acf8f91a0 -Author: djm@openbsd.org -Date: Tue Jun 11 00:44:52 2024 +0000 +commit 83729cf503289104d7e64a69be14579523988cb6 +Author: Damien Miller +Date: Wed May 21 18:47:46 2025 +1000 - upstream: reap the [net] child if it hangs up while writing privsep + merge netcat SOCKS4A support from OpenBSD - message payloads, not just the message header + Not a full sync of this file as we have diverged substantially + from upstream (it has libtls support, etc.) + +commit 750f1867476bda36879f69e25e8f52cb45c58807 +Author: Darren Tucker +Date: Tue May 20 22:17:02 2025 +1000 + + Include OpenSSL compat shim where needed. + +commit 6fb728df50c1afd338cb0223a84ce24579577eff +Author: Darren Tucker +Date: Tue May 20 19:28:55 2025 +1000 + + Run all tests on Cygwin again. - OpenBSD-Commit-ID: 24dbd400aa381ac96be7ed2dd49018487dfef6ce + ... now that we've fixed ci-setup on Cygwin. -commit 6211aa085fa91155a24922e5329576ac9a8f3175 -Author: djm@openbsd.org -Date: Tue Jun 11 00:40:21 2024 +0000 +commit 648a3a008cf1cfa54631d2f0457b5313c455f484 +Author: Darren Tucker +Date: Tue May 20 18:48:23 2025 +1000 - upstream: log waitpid() status for abnormal exits + Use USERNAME rather than LOGNAME on Cygwin. - OpenBSD-Commit-ID: b317930e06b51819c1a2bc6a4359764fecfb1c2d + LOGNAME is specified by POSIX, but Windows (or at least, github's + Windows images) don't set it. -commit a59634c7adb9ae988748d99963dfafb3070d8d41 -Author: djm@openbsd.org -Date: Tue Jun 11 00:36:20 2024 +0000 +commit 0214e53124c09528b6ee29b9a551442b5611a454 +Author: Darren Tucker +Date: Tue May 20 18:28:52 2025 +1000 - upstream: correct error message + Add debug output when setting up CI environment. + +commit 9d9a2c0369419f3b4952e597db7b8696f54e7f3a +Author: Darren Tucker +Date: Tue May 20 19:16:38 2025 +1000 + + Include openssl compat shims in test. - OpenBSD-Commit-ID: 581f60f73099083392887206860229ab104620ed + Fixes tests on platforms using older LibreSSL releases prior to 3.4. -commit fa7d7a667f2ee031e72873e36de2d2a36bca973b -Author: deraadt@openbsd.org -Date: Fri Jun 7 13:23:30 2024 +0000 +commit 1a9b1cfa4e8b807c7f82fdba8f730c2abdbba071 +Author: Darren Tucker +Date: Tue May 20 18:14:06 2025 +1000 - upstream: avoid shadowing issues which some compilers won't accept + Add compat shims for EC_POINT affine_coordinates - ok djm + LibreSSL <3.4 does not have EC_POINT_[gs]et_affine_coordinates + but does have the now-deprecated _GFp variantes. We still support + LibreSSL back as far as 3.2.x so add a compat shim. + +commit cff2175200b412a9207a4fe5c1bdcc54e8a73d07 +Author: tb@openbsd.org +Date: Mon May 12 05:42:02 2025 +0000 + + upstream: Use EC_POINT_[sg]et_affine_coordinates() - OpenBSD-Commit-ID: 1e89572397dda83433d58c4fa6333a08f51170d4 + It is available in all supported OpenSSL flavors/versions and the _GFp + variants will be removed from LibreSSL. + + ok hshoexer jsing + + OpenBSD-Regress-ID: 66cf1561e7b6c49002978f2d6720956f33a882f0 -commit 3ad4cd9eeca5c9bc6706db44b6de88e2e4513fd6 -Author: jmc@openbsd.org -Date: Thu Jun 6 21:14:49 2024 +0000 +commit 2d35e24739b515394017b74465a0996c384cf28f +Author: tb@openbsd.org +Date: Mon May 12 05:41:20 2025 +0000 - upstream: escape the final dot at eol in "e.g." to avoid double + upstream: Use EC_POINT_[sg]et_affine_coordinates() - spacing; + It is available in all supported OpenSSL flavors/versions and the _GFp + variants will be removed from LibreSSL. - OpenBSD-Commit-ID: 0a9fb10bc9f7d577afe2da3f498a08bc431115b9 + ok hshoexer jsing + + OpenBSD-Commit-ID: ecedca0e1ffa80e0c9ef7c787bc6a972882c596b -commit 0e0c69761a4c33ccd4a256560f522784a753d1a8 +commit 17003b9f1cd7b7bf1f52493cc4a1ab95727c3ed7 Author: djm@openbsd.org -Date: Thu Jun 6 20:25:48 2024 +0000 +Date: Fri May 9 02:42:03 2025 +0000 - upstream: enable PerSourcePenalties by default. + upstream: make the progress-meter code safe against being called - ok markus + when not initialised; spotted by tb@ feedback/ok tb@ deraadt@ - NB. if you run a sshd that accepts connections from behind large NAT - blocks, proxies or anything else that aggregates many possible users - behind few IP addresses, then this change may cause legitimate traffic - to be denied. + OpenBSD-Commit-ID: a9fda1ee08a24c62e0981ff6d15ca93b63467038 + +commit 2d023e7a95d673e93ccc1978bf8931f7335b2b53 +Author: tedu@openbsd.org +Date: Thu May 8 17:32:53 2025 +0000 + + upstream: convert a last quad_t to int64_t. ok deraadt djm - Please read the PerSourcePenalties, PerSourcePenaltyExemptList and - PerSourceNetBlockSize options in sshd_config(5) for how to tune your - sshd(8) for your specific circumstances. + OpenBSD-Commit-ID: 1c9e01ba1a9ccf442a9cdf10f222077f66885f1f + +commit fc8c56ade809f66f7df4b5153a4d92593631c12a +Author: Darren Tucker +Date: Tue May 20 15:01:29 2025 +1000 + + Set runner pasword to random string. - OpenBSD-Commit-ID: 24a0e5c23d37e5a63e16d2c6da3920a51078f6ce + The most recent version of the Github ubuntu-latest image sets the + password field to "!" which sshd considers to be a locked account, + breaking most of the tests. -commit bd1f74741daabeaf20939a85cd8cec08c76d0bec -Author: djm@openbsd.org -Date: Thu Jun 6 20:20:42 2024 +0000 +commit c404686c17daeda7e95ca6fc14c8a4a570cf975d +Author: Darren Tucker +Date: Sun May 11 22:54:13 2025 +1000 + + Debug log for why an account is considered locked. + +commit ee1d31781cf0d292a50b4df4cb8cb6ffcbfbe9af +Author: Darren Tucker +Date: Sun May 11 16:35:31 2025 +1000 + + Move debug log output into separate workflow step. + + Should reduce the need to scroll back to find out which test actually + failed. + +commit ddfb78a15f57a33427d462b9c401de5c8e6799da +Author: Darren Tucker +Date: Sat May 10 21:48:06 2025 +1000 + + Skip sftp-perm on Cygwin too. + +commit 8846caccb86b3f5a4f1c10bfffcc9cf1adc17925 +Author: Darren Tucker +Date: Sat May 10 10:23:30 2025 +1000 + + Remove CYGWIN binmode as it's now obsolete. + +commit cf795d55437e6c1ffe85e90e0fae00e885e50036 +Author: Darren Tucker +Date: Sat May 10 09:25:18 2025 +1000 - upstream: mention that PerSourcePenalties don't affect concurrent + Also skip sftp-cmds test on Cygwin. - in-progress connections. + Fails at the hardlink step. + +commit d1b28639c1cb382943bd92c68992ea74af9b5773 +Author: Darren Tucker +Date: Sat May 10 08:52:11 2025 +1000 + + Tell Cygwin to use native symlinks. + +commit 56782dad7d7f96b4943951227515bd7904ac3cf7 +Author: Darren Tucker +Date: Sat May 10 08:26:37 2025 +1000 + + Skip keygen-knownhost test on Cygwin. - OpenBSD-Commit-ID: 20389da6264f2c97ac3463edfaa1182c212d420c + It fails but at this time it's not clear why. -commit 9774b938578327d88a651f4c63c504809717590a -Author: djm@openbsd.org -Date: Thu Jun 6 19:49:25 2024 +0000 +commit d5cbac2364b03e55b733a2422a07e78e16d2a118 +Author: Darren Tucker +Date: Sat May 10 07:59:44 2025 +1000 - upstream: regress test for PerSourcePenalties + Pass Cygwin setup location to CI setup. - OpenBSD-Regress-ID: a1af13d411b25a727742644459d26480b9a1b0f1 + (instead of hard coding it, wrongly). -commit b8ebd86cefe9812204a10c028dc90de29918667d -Author: djm@openbsd.org -Date: Thu Jun 6 19:48:40 2024 +0000 +commit 82f1f52c5582f005761e4e200c279ddd9c6781e4 +Author: Darren Tucker +Date: Sat May 10 06:37:24 2025 +1000 - upstream: make sure logs are saved from sshd run via start_sshd + Add RUN_ONLY_TEST to limit which tests are run. - OpenBSD-Regress-ID: de4ef0e32e3ab85ff3a6c36eb08d1909c0dd1b4a + For testing, you can set the repo variable RUN_ONLY_TEST in your repo + (Repo -> Settings -> Security -> Actions -> Variables) to run only that test. -commit d7b2070bdaa4ebbfafb9975c1d5a62b73289d31f -Author: djm@openbsd.org -Date: Thu Jun 6 19:47:48 2024 +0000 +commit 140ba45895de8ebfb3e2517b0ddee58729979c29 +Author: Darren Tucker +Date: Fri May 9 19:32:06 2025 +1000 - upstream: simplify + Move misc-agent.o to LIBSSH_OBJS. - OpenBSD-Regress-ID: 50316e0d1ae0c0a057a45af042253e54ce23d11c + It's needed by the fuzzer. -commit e6ea3d224513b6bfb93818809d4c7397f5995ba2 -Author: djm@openbsd.org -Date: Thu Jun 6 18:48:13 2024 +0000 +commit 3357bf2fe2d11b6ed4465c1ed2871bd1099cbbc5 +Author: Darren Tucker +Date: Fri May 9 19:08:36 2025 +1000 - upstream: prepare for PerSourcePenalties being enabled by default + Put PRIV_ECDSA back, it's still used. - in future + Should fix oss-fuzz test. + +commit f5726215957bb34e18bb872d527845c2f64e2389 +Author: Darren Tucker +Date: Thu May 8 18:56:39 2025 +1000 + + Since it's unused, make dirfd() take void *. - OpenBSD-Regress-ID: 5236c6d1c823997aac5a35e2915da30f1903bec7 + Some platforms (eg Old BSDs) in some configurations define DIR to "void + *", which causes compile errors in the no-op implementation. -commit c0cb3b8c837761816a60a3cdb54062668df09652 -Author: djm@openbsd.org -Date: Thu Jun 6 19:50:01 2024 +0000 +commit 1511f113a27d8aafe080aa6493cb3c0cf2b5abe0 +Author: Darren Tucker +Date: Thu May 8 11:38:24 2025 +1000 - upstream: disable stderr redirection before closing fds + Add no-op implmentation of dirfd(). - OpenBSD-Commit-ID: d42cb895ee4542098050367fc35321c9303f003a + Fixes build on pre-POSIX.1 2008 systems. -commit 81c1099d22b81ebfd20a334ce986c4f753b0db29 -Author: djm@openbsd.org -Date: Thu Jun 6 17:15:25 2024 +0000 +commit 086369736a9496b39af0d9f09443fa81b59b7f05 +Author: Daniel Kahn Gillmor +Date: Wed Apr 16 10:18:34 2025 +1000 - upstream: Add a facility to sshd(8) to penalise particular + ssh-agent: exit 0 from SIGTERM under systemd socket-activation - problematic client behaviours, controlled by two new sshd_config(5) options: - PerSourcePenalties and PerSourcePenaltyExemptList. + When the ssh-agent service is configured to be launched under systemd + socket-activation, the user can inspect the status of the agent with + something like: - When PerSourcePenalties are enabled, sshd(8) will monitor the exit - status of its child pre-auth session processes. Through the exit - status, it can observe situations where the session did not - authenticate as expected. These conditions include when the client - repeatedly attempted authentication unsucessfully (possibly indicating - an attack against one or more accounts, e.g. password guessing), or - when client behaviour caused sshd to crash (possibly indicating - attempts to exploit sshd). + systemctl --user status ssh-agent.service - When such a condition is observed, sshd will record a penalty of some - duration (e.g. 30 seconds) against the client's address. If this time - is above a minimum threshold specified by the PerSourcePenalties, then - connections from the client address will be refused (along with any - others in the same PerSourceNetBlockSize CIDR range). + If the user does: - Repeated offenses by the same client address will accrue greater - penalties, up to a configurable maximum. A PerSourcePenaltyExemptList - option allows certain address ranges to be exempt from all penalties. + systemctl --user stop ssh-agent.service - We hope these options will make it significantly more difficult for - attackers to find accounts with weak/guessable passwords or exploit - bugs in sshd(8) itself. + it causes the `systemd --user` supervisor to send a SIGTERM to the + agent, which terminates while leaving the systemd-managed socket in + place. That's good, and as expected. (If the user wants to close the + socket, they can do "systemctl --user stop ssh-agent.socket" instead) - PerSourcePenalties is off by default, but we expect to enable it - automatically in the near future. + But because ssh-agent exits with code 2 in response to a SIGTERM, the + supervisor marks the service as "failed", even though the state of the + supervised service is exactly the same as during session startup (not + running, ready to launch when a client connects to the socket). - much feedback markus@ and others, ok markus@ + This change makes ssh-agent exit cleanly (code 0) in response to a + SIGTERM when launched under socket activation. This aligns the systemd + supervisor's understanding of the state of supervised ssh-agent with + reality. - OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca + Signed-off-by: Daniel Kahn Gillmor -commit 916b0b6174e203cf2c5ec9bcf409472eb7ffbf43 -Author: Damien Miller -Date: Fri Jun 7 03:31:02 2024 +1000 +commit 755c3d082e59e6884f28d30e6333a1444e9173d1 +Author: Darren Tucker +Date: Wed May 7 21:05:06 2025 +1000 - whitespace + Skip d_type check on platforms that don't have it. + + On those, the subsequent stat() should catch the sockets. -commit 49b55e44182b8294419aa580cbf043d5b9e3d953 -Author: deraadt@openbsd.org -Date: Tue Jun 4 15:14:45 2024 +0000 +commit 207289a5663bdf49903e1aeb938dcc0924e2ac63 +Author: dtucker@openbsd.org +Date: Wed May 7 10:44:26 2025 +0000 - upstream: enable -fret-clean on amd64, for libc libcrypto ld.so + upstream: Rename sockaddr_un sun -> sunaddr. - kernel, and all the ssh tools. The dynamic objects are entirely ret-clean, - static binaries will contain a blend of cleaning and non-cleaning callers. + This makes things easier in -portable, where on Solaris an derivatives + "sun" is defined to "1", causing compilation errors. ok deraadt@. - OpenBSD-Commit-ID: 112aacedd3b61cc5c34b1fa6d9fb759214179172 + OpenBSD-Commit-ID: 0669043afb49856b57b382f0489221bd98305d3b -commit cc80d51d034bcb24fd0f2564a4bdf1612000a2a2 -Author: Damien Miller -Date: Wed Jun 5 02:21:30 2024 +1000 +commit 7cc8e150d51a4545b86d996692b541419b35d1a3 +Author: djm@openbsd.org +Date: Tue May 6 06:05:48 2025 +0000 - remove PRIVSEP macros for osx + upstream: remove DSA from the regression/unit test suite too. + + OpenBSD-Regress-ID: 4424d2eaf0bce3887318ef6d18de6c06f3617d6e -commit 8785491123d4d722b310c20f383570be758f8263 +commit 0404fa799746c283325a463c363436eb152daefc Author: djm@openbsd.org -Date: Sat Jun 1 07:03:37 2024 +0000 +Date: Tue Apr 15 05:31:24 2025 +0000 - upstream: be really strict with fds reserved for communication with the + upstream: another missing ifdef - separate sshd-session process - reserve them early and fatal if we can't - dup2(2) them later. The pre-split fallback to re-reading the configuration - files is not possible, so sshd-session absolutely requires the fd the - configuration is passed over to be in order. - - ok deraadt@ - - OpenBSD-Commit-ID: 308a98ef3c8a6665ebf92c7c9a0fc9600ccd7065 + OpenBSD-Regress-ID: 4f71f8f122eac4cbf7f1d2088a9be45317dd3e4a -commit f1c8918cb98459910fb159373baea053ba4108c0 -Author: Damien Miller -Date: Fri May 31 19:12:26 2024 +1000 +commit c5dbbe8805caaee132545ab4cffd3b2221e80975 +Author: djm@openbsd.org +Date: Tue Apr 15 05:00:13 2025 +0000 - depend + upstream: missing ifdef + + OpenBSD-Regress-ID: 7260fb672de5738c17dec06c71a5be0186bb2b09 -commit 94b4866cb1f4b0ed29a9f367047b30f81002316f -Author: Damien Miller -Date: Fri May 31 19:11:14 2024 +1000 +commit 93e904a673a632604525fdc98b940b7996f1ce54 +Author: djm@openbsd.org +Date: Wed May 7 04:10:21 2025 +0000 - rename need_privsep to need_chroot + upstream: memory leak on error path; bz3821 - privsep is mandatory, chroot is optional (disabled when running - sshd as non-root) + OpenBSD-Commit-ID: 65577596a15ad6dd9a1ab3fc24c1c31303ee6e2b -commit e68a95142e5024b144f8eeccd5ffdee42c34f44c -Author: Damien Miller -Date: Fri May 31 19:05:34 2024 +1000 +commit 55b38ff4d7286c8fac2a472da664462e0f2d75e0 +Author: deraadt@openbsd.org +Date: Tue May 6 15:15:05 2025 +0000 - remove remaining use_privsep mention + upstream: test ssh-agent with the -T flag to force the old /tmp + + location rather than inside the homedir. During relink operation, + /.ssh/agent was created which is surprising. This test sequence could use + some improvement so this is a temporary fix. observed by florian, change ok + semarie + + OpenBSD-Commit-ID: c7246a6b519ac390ca550719f91acfdaef1fa0f0 -commit b21d271f651d2536dca819cc6d74032fe98634db +commit a32d28d792567253bb601362f36391f155f8f772 Author: djm@openbsd.org -Date: Fri May 31 09:01:08 2024 +0000 +Date: Tue May 6 05:40:56 2025 +0000 - upstream: warn when -r (deprecated option to disable re-exec) is + upstream: finally remove DSA signature support from OpenSSH. - passed + feedback/ok tb@, ok deraadt@ - OpenBSD-Commit-ID: 73145ef5150edbe3ce7889f0844ed8fa6155f551 + OpenBSD-Commit-ID: bfe6ee73c1b676c81a2901030c791f8ec888228f -commit a4b5bc246cbca476deeeb4462aa31746a56e3021 +commit 928f8dcc1bb622c25be409c34374b655d0149373 Author: djm@openbsd.org -Date: Fri May 31 08:49:35 2024 +0000 +Date: Mon May 5 05:51:11 2025 +0000 - upstream: typos + upstream: Now that there's an I-D for certificate keys, refer to - OpenBSD-Commit-ID: edfa72eb06bfa65da30fabf7d2fe76d2d33f77bf + that instead of the much more basic format description we had previously. + + OpenBSD-Commit-ID: cf01e0727a813fee8626ad7b3aa240621cc92014 -commit 8054b906983ceaed01fabd8188d3dac24c05ba39 -Author: djm@openbsd.org -Date: Mon May 27 01:52:26 2024 +0000 +commit fe883543bece18c975fa53aa02104f0433645d99 +Author: jmc@openbsd.org +Date: Mon May 5 05:47:28 2025 +0000 - upstream: don't need sys/queue.h here + upstream: - add full stop to the text in -a - move the -U and -u - OpenBSD-Commit-ID: dd137396828171eb19e4911581812ca58de6c578 + text to the correct place + + OpenBSD-Commit-ID: 2fb484337a0978c703f61983bb14bc5cbaf898c2 -commit 210d4239733da6180ce853538aeb9413d5c62ad5 -Author: naddy@openbsd.org -Date: Sun May 26 20:35:12 2024 +0000 +commit 5fd6ef297dec23e3574646b6334087131230d0a6 +Author: Darren Tucker +Date: Tue May 6 19:01:00 2025 +1000 - upstream: remove references to SSH1 and DSA server keys + Add minimal implementations of fstatat and unlinkat. - OpenBSD-Commit-ID: 57cc1c98d4f998981473734f144b904af7d178a2 + Fixes build on some pre-POSIX.1-2008 platforms. -commit f0b9261d7fdd0ef86806b49fe76344bd16770cd0 -Author: jsg@openbsd.org -Date: Thu May 23 23:47:16 2024 +0000 +commit d2480827b3ef6ec119965822afdff35d734b2dee +Author: Darren Tucker +Date: Tue May 6 08:15:34 2025 +1000 - upstream: remove unused struct fwd_perm_list, no decl with complete - - type ok djm@ - - OpenBSD-Commit-ID: 416fb3970b7e73c76d2963c4f00cf96f2b2ee2fb + New location of cygwin setup. -commit 2477a98c3ef78e63b11a1393656e00288f52ae97 -Author: naddy@openbsd.org -Date: Wed May 22 15:24:55 2024 +0000 +commit 57eb87b15bd0343372f99d661ce95efb25a16f1e +Author: Darren Tucker +Date: Tue May 6 08:07:23 2025 +1000 - upstream: Do not pass -Werror twice when building with clang. - - OpenBSD-Commit-ID: 5f378c38ad8976d507786dc4db9283a879ec8cd0 + Boringssl now puts libcrypto in a different place. -commit 435844f5675245b4271f8581f15e6d1f34fde3bc -Author: miod@openbsd.org -Date: Wed May 22 11:49:36 2024 +0000 +commit 61525ba967ac1bb7394ea0792aa6030bcbbad049 +Author: Darren Tucker +Date: Mon May 5 20:45:42 2025 +1000 - upstream: Do not pass -Werror if building with gcc 3, for asn1.h + Handle systems that don't have st_mtim. - and bio.h cause (admittedly bogus) warnings with gcc 3. + Ignores nanoseconds, but it's checking for >1h old so a few nanoseconds + shouldn't matter much. Fixes build on Mac OS X. + +commit 27861e9b15151898841097c14ee974c026093131 +Author: Darren Tucker +Date: Mon May 5 19:09:25 2025 +1000 + + Supply timespecsub if needed. + +commit 7c0e6626e4be53efcfbb92f0c6382a76f1138e38 +Author: Darren Tucker +Date: Mon May 5 19:08:48 2025 +1000 + + includes.h for compat, time.h for clock_gettime. + +commit 7a7cc3cf721fe7fe9f4925d92bb7c694b8550a7f +Author: Darren Tucker +Date: Mon May 5 18:51:34 2025 +1000 + + Cygwin install in back on D: + +commit 6ab8133c067a8e91ba69ce7ca04f95b50f2f2d7b +Author: Damien Miller +Date: Mon May 5 14:59:30 2025 +1000 + + depend + +commit 12912429cf39cfeca97dd18a8f875ad9824d1751 +Author: djm@openbsd.org +Date: Mon May 5 03:35:06 2025 +0000 + + upstream: missing file in previous commit - OpenBSD-Commit-ID: fb39324748824cb0387e9d67c41d1bef945c54ea + OpenBSD-Commit-ID: e526c97fcb2fd9f0b7b229720972426ab437d7eb -commit fc5dc092830de23767c6ef67baa18310a64ee533 +commit 80162f9d7e7eadca4ffd0bd1c015d38cb1821ab6 Author: djm@openbsd.org -Date: Wed May 22 04:20:00 2024 +0000 +Date: Mon May 5 02:48:06 2025 +0000 - upstream: this test has been broken since 2014, and has been + upstream: Move agent listener sockets from /tmp to under - testing the same key exchange algorithm repeatedly instead of testing all of - them. Spotted by nreilly AT blackberry.com in bz3692 + ~/.ssh/agent for both ssh-agent(1) and forwarded sockets in sshd(8). - Who broke the test? me. + This ensures processes (such as Firefox) that have restricted + filesystem access that includes /tmp (via unveil(3)) do not have the + ability to use keys in an agent. - OpenBSD-Regress-ID: 48f4f5946276f975667141957d25441b3c9a50e2 + Moving the default directory has the consequence that the OS will no + longer clean up stale agent sockets, so ssh-agent now gains this + ability. + + To support $HOME on NFS, the socket path includes a truncated hash of + the hostname. ssh-agent will by default only clean up sockets from + the same hostname. + + ssh-agent gains some new flags: -U suppresses the automatic cleanup + of stale sockets when it starts. -u forces a cleanup without + keeping a running agent, -uu forces a cleanup that ignores the + hostname. -T makes ssh-agent put the socket back in /tmp. + + feedback deraadt@ naddy@, doitdoitdoit deraadt@ + + OpenBSD-Commit-ID: 8383dabd98092fe5498d5f7f15c7d314b03a93e1 -commit fd4816791beaed2fdae7eea3e1494d1972b2a39d -Author: anton@openbsd.org -Date: Sun May 19 19:10:01 2024 +0000 +commit 566443b5f5d7bc4c5310313b4e46232760850c7a +Author: djm@openbsd.org +Date: Mon May 5 02:40:30 2025 +0000 - upstream: Add missing kex-names.c source file required since the + upstream: correct log messages; the reap function is used for more - ssh split. + than just the preauth process now - OpenBSD-Regress-ID: ca666223f828fc4b069cb9016bff1eb50faf9fbb + OpenBSD-Commit-ID: 768c5b674bd77802bb197c31dba78559f1174c02 -commit beccb7319c5449f6454889013403c336446d622e -Author: naddy@openbsd.org -Date: Fri May 17 14:42:00 2024 +0000 +commit e048230106fb3f5e7cc07abc311c6feb5f52fd05 +Author: djm@openbsd.org +Date: Wed Apr 30 05:26:15 2025 +0000 - upstream: remove duplicate copy of relink kit for sshd-session + upstream: make writing known_hosts lines more atomic, by writing - OpenBSD-Commit-ID: 6d2ded4cd91d4d727c2b26e099b91ea935bed504 + the entire line in one operation and using unbuffered stdio. + + Usually writes to this file are serialised on the "Are you sure you + want to continue connecting?" prompt, but if host key checking is + disabled and connections were being made with high concurrency + then interleaved writes might have been possible. + + feedback/ok deraadt@ millert@ + + OpenBSD-Commit-ID: d11222b49dabe5cfe0937b49cb439ba3d4847b08 -commit dcd79fa141311c287e0595ede684b7116122fae0 -Author: jsg@openbsd.org -Date: Fri May 17 06:42:04 2024 +0000 +commit c991273c18afc490313a9f282383eaf59d9c13b9 +Author: djm@openbsd.org +Date: Wed Apr 30 05:23:15 2025 +0000 - upstream: remove prototypes with no matching function; ok djm@ + upstream: fix a out-of-bounds read if the known_hosts file is - OpenBSD-Commit-ID: 6d9065dadea5f14a01bece0dbfe2fba1be31c693 + truncated after the hostname. + + Reported by the OpenAI Security Research Team + + ok deraadt@ + + OpenBSD-Commit-ID: c0b516d7c80c4779a403826f73bcd8adbbc54ebd -commit 6454a05e7c6574d70adf17efe505a8581a86ca4f -Author: jsg@openbsd.org -Date: Fri May 17 06:38:00 2024 +0000 +commit b5b405fee7f3e79d44e2d2971a4b6b4cc53f112e +Author: Darren Tucker +Date: Sun Apr 20 09:07:57 2025 +1000 - upstream: remove externs for removed vars; ok djm@ + Set Windows permssions on regress dir. - OpenBSD-Commit-ID: f51ea791d45c15d4927eb4ae7d877ccc1e5a2aab + Prevents "unprotected private key file" error when running tests. -commit f3e4db4601ef7d2feb1d6f7447e432aaf353a616 -Author: deraadt@openbsd.org -Date: Fri May 17 06:11:17 2024 +0000 +commit 76631fdd04824c3e50ea6551d3611b1fe0216a41 +Author: Darren Tucker +Date: Fri Apr 18 08:18:52 2025 +1000 - upstream: -Werror was turned on (probably just for development), - - and this is a simple way to satisfy older gcc. - - OpenBSD-Commit-ID: 7f698df54384b437ce33ab7405f0b86c87019e86 + Add 10.0 branch to test status page. -commit 24a1f3e5ad6f4a49377d4c74c36637e9a239efd0 -Author: Damien Miller -Date: Fri May 17 14:50:43 2024 +1000 +commit c627b468d3b99e487e2b24c90958ae57e633d681 +Author: Darren Tucker +Date: Fri Apr 18 08:14:16 2025 +1000 - attempt at updating RPM specs for sshd-session + cygwin-install-action now puts setup.exe on D: -commit 17b566eeb7a0c6acc9c48b35c08885901186f861 -Author: djm@openbsd.org -Date: Fri May 17 04:42:13 2024 +0000 +commit 52bddbc1a7f53a1e5c871767913648eb639ac6d5 +Author: Darren Tucker +Date: Fri Apr 18 08:10:32 2025 +1000 - upstream: g/c unused variable + Include time.h for clock_gettime(). + +commit 9b50cb171b5c56184ce6fa3994ce62f9882d2daf +Author: Darren Tucker +Date: Thu Apr 17 16:51:14 2025 +1000 + + Add includes.h for new tests. - OpenBSD-Commit-ID: aa6ef0778a1f1bde0d73efba72a777c48d2bd010 + Fixes builds on older platforms. -commit 01fb82eb2aa0a4eaf5c394ea8bb37ea4c26f8a3f -Author: jsg@openbsd.org -Date: Fri May 17 02:39:11 2024 +0000 +commit 46e52fdae08b89264a0b23f94391c2bf637def34 +Author: Darren Tucker +Date: Wed Apr 16 22:29:17 2025 +1000 - upstream: spelling; ok djm@ + Provide INFINITY if it's not provided. - OpenBSD-Commit-ID: bdea29bb3ed2a5a7782999c4c663b219d2270483 + INFINITY is specified in c99, so define if not provided. -commit b88b690e99145a021fc1a1a116a11e0bce0594e7 -Author: djm@openbsd.org -Date: Fri May 17 01:45:22 2024 +0000 +commit 849c2fd894aa87a7e40c71e8d5bda5392b1205be +Author: Darren Tucker +Date: Tue Apr 15 21:58:49 2025 +1000 - upstream: allow overriding the sshd-session binary path + Look for sqrt(), possibly in libm. - OpenBSD-Regress-ID: 5058cd1c4b6ca1a15474e33546142931d9f964da + The unit tests now use sqrt(), which in some platforms (notably + DragonFlyBSD and Solaris) is not in libc but rather libm. Since only + the unit tests use this, add TESTLIBS and if necessary put libm in it. -commit a68f80f2511f0e0c5cef737a8284cc2dfabad818 -Author: anton@openbsd.org -Date: Wed Apr 3 06:01:11 2024 +0000 +commit 1ec5b39f1f673beac039bb42c98a11aa2b08a0b2 +Author: dtucker@openbsd.org +Date: Tue Apr 15 09:22:25 2025 +0000 - upstream: Since ssh-agent(1) is only readable by root by now, use + upstream: Cast signalled_keydrop to int when logging to prevent warning - ssh(1) while generating data in tests. + on platforms where sig_atomic_t is not the same as int. bz#3811, patch from + jlduran at gmail com. - OpenBSD-Regress-ID: 24eb40de2e6b0ace185caaba35e2d470331ffe68 + OpenBSD-Commit-ID: b6bc9e9006e7f81ade57d41a48623a4323deca6c -commit 92e55890314ce2b0be21a43ebcbc043b4abc232f +commit f3d465530e75cb6c02e2cde1d15e6c4bb51ebfd9 Author: djm@openbsd.org -Date: Fri May 17 01:17:40 2024 +0000 +Date: Tue Apr 15 04:00:42 2025 +0000 - upstream: fix incorrect debug option name introduce in previous + upstream: basic benchmarking support for the unit test framework enable - commit + with "make UNITTEST_BENCHMARK=yes" - OpenBSD-Commit-ID: 66d69e22b1c072c694a7267c847f212284614ed3 + ok dtucker@ + + OpenBSD-Regress-ID: 7f16a2e247f860897ca46ff87bccbe6002a32564 -commit 4ad72878af7b6ec28da6e230e36a91650ebe84c1 -Author: deraadt@openbsd.org -Date: Fri May 17 00:33:25 2024 +0000 +commit 609fe2cae2459d721ac11d23cd27b8a94397ef3c +Author: jmc@openbsd.org +Date: Mon Apr 14 05:41:42 2025 +0000 - upstream: construct and install a relink-kit for sshd-session ok + upstream: rework the text for -3 to make it clearer what default - djm + behaviour is, and adjust the text for -R to make them more consistent; - OpenBSD-Commit-ID: 8b3820adb4da4e139c4b3cffbcc0bde9f08bf0c6 + issue raised by mikhail mp39590; + behaviour explained by naddy + + ok djm + + OpenBSD-Commit-ID: 15ff3bd1518d86c84fa8e91d7aa72cfdb41dccc8 -commit 02e679a2cb3f6df8e9dbb1519ed578226485157f +commit 8725dbc5b5fcc3e326fc71189ef8dba4333362cc Author: Damien Miller -Date: Fri May 17 12:21:27 2024 +1000 +Date: Wed Apr 9 17:02:17 2025 +1000 - Makefile support for sshd-session + update version numbers -commit c0416035c5eaf70a8450d11c8833c5f7068ee7ad +commit cc7feb9458ad3b893b53dc9c7500d1affd208bde Author: djm@openbsd.org -Date: Fri May 17 00:32:32 2024 +0000 +Date: Wed Apr 9 07:00:21 2025 +0000 - upstream: missing files from previous + upstream: openssh-10.0 - OpenBSD-Commit-ID: 4b7be4434d8799f02365552b641a7a70a7ebeb2f + OpenBSD-Commit-ID: db5b4a1f1c9e988f8f166b56dc5643606294b403 -commit 03e3de416ed7c34faeb692967737be4a7bbe2eb5 +commit fc86875e6acb36401dfc1dfb6b628a9d1460f367 Author: djm@openbsd.org -Date: Fri May 17 00:30:23 2024 +0000 +Date: Wed Apr 9 07:00:03 2025 +0000 - upstream: Start the process of splitting sshd into separate - - binaries. This step splits sshd into a listener and a session binary. More - splits are planned. - - After this changes, the listener binary will validate the configuration, - load the hostkeys, listen on port 22 and manage MaxStartups only. All - session handling will be performed by a new sshd-session binary that the - listener fork+execs. - - This reduces the listener process to the minimum necessary and sets us - up for future work on the sshd-session binary. - - feedback/ok markus@ deraadt@ + upstream: Fix logic error in DisableForwarding option. This option - NB. if you're updating via source, please restart sshd after installing, - otherwise you run the risk of locking yourself out. + was documented as disabling X11 and agent forwarding but it failed to do so. + Spotted by Tim Rice. - OpenBSD-Commit-ID: 43c04a1ab96cdbdeb53d2df0125a6d42c5f19934 + OpenBSD-Commit-ID: fffc89195968f7eedd2fc57f0b1f1ef3193f5ed1 -commit 1c0d81357921f8d3bab06841df649edac515ae5b +commit dd73459e351b0a2908aed90910c8ff9b0b381c6d Author: djm@openbsd.org -Date: Thu May 9 09:46:47 2024 +0000 +Date: Wed Apr 9 01:24:40 2025 +0000 - upstream: simplify exit message handling, which was more complicated - - than it needed to be because of unexpunged ssh1 remnants. ok markus@ + upstream: oops, I accidentally backed out the typo fix - OpenBSD-Commit-ID: 8b0cd2c0dee75fb053718f442aa89510b684610b + OpenBSD-Commit-ID: f485f79bf3e9ebbe1de13ac96150cf458956cfd8 -commit cbbbf76aa6cd54fce32eacce1300e7abcf9461d4 -Author: tobias@openbsd.org -Date: Mon May 6 19:26:17 2024 +0000 +commit 0cb945891944bada5850e85d60afa3c807cf1af6 +Author: djm@openbsd.org +Date: Wed Apr 9 01:23:47 2025 +0000 - upstream: remove SSH1 leftovers - - Authored with Space Meyer - - ok djm + upstream: typo - OpenBSD-Commit-ID: 81db602e4cb407baae472689db1c222ed7b2afa3 + OpenBSD-Commit-ID: f912725c7d303720706b3ccfb2cb846d46296d13 -commit bc5dcb8ab9a4e8af54a724883732af378f42ea78 -Author: tobias@openbsd.org -Date: Tue Apr 30 15:40:43 2024 +0000 +commit cd4a6bd50b658d707867caa1f5aa40b35c2b6c19 +Author: Damien Miller +Date: Wed Apr 9 09:49:55 2025 +1000 - upstream: never close stdin - - The sanitise_stdfd call makes sure that standard file descriptors are - open (if they were closed, they are connected with /dev/null). + initialise websafe_allowlist in agent fuzzer + +commit 55b7cb48af96c1102ef8ab5a73bb329cbed30945 +Author: djm@openbsd.org +Date: Tue Apr 8 23:10:46 2025 +0000 + + upstream: typo - Do not close stdin in any case to prevent error messages when stdin is - read multiple times and to prevent later usage of fd 0 for connections, - e.g. + OpenBSD-Regress-ID: 08477b936d1d0c1e8a98aa1c0e1bdde8871894c9 + +commit 985d8cbcd3438cc36b4e709476f1783e358ddfb1 +Author: djm@openbsd.org +Date: Tue Apr 8 23:10:08 2025 +0000 + + upstream: typo - echo localhost | ssh-keyscan -f - -f - + OpenBSD-Commit-ID: 6e683e13e72bf1e43bbd3bbc6a8332d5a98bdc99 + +commit 000c3d14e94d8f7597087c457260ea9417045b65 +Author: dtucker@openbsd.org +Date: Mon Apr 7 08:12:22 2025 +0000 + + upstream: Include time.h for time(). - While at it, make stdin-related error messages nicer. + Fixes warning on some platforms when building without openssl. - Authored with Max Kunzelmann + OpenBSD-Commit-ID: 04ca29b8eaae1860c7adde3e770baa1866e30a54 + +commit 49b8b9bf829e08af22366530614a5e59ac341ca9 +Author: tb@openbsd.org +Date: Wed Apr 2 04:28:03 2025 +0000 + + upstream: Wrap #include in #ifdef WITH_DSA ok djm - OpenBSD-Commit-ID: 48e9b7938e2fa2f9bd47e6de6df66a31e0b375d3 + OpenBSD-Commit-ID: ed01a7c102243f84e4a317aefb431916d98aab15 -commit 6a42b70e56bef1aacdcdf06352396e837883e84f +commit f80fb819e5521e13f167edbcc3eed66e22ad0c2a Author: Damien Miller -Date: Wed May 8 09:43:59 2024 +1000 +Date: Thu Apr 3 09:10:19 2025 +1100 - sync getrrsetbyname.c with recent upstream changes + remove all instances of -pie from LDFLAGS + + Previously only the first instance of this flag was removed. + Unbreaks build on OpenSUSE Tumbleweed. Patch from Antonio Larrosa -commit 385ecb31e147dfea59c1c488a1d2011d3867e60e +commit 6c9872faa1c297a84c6d3e3b95a927be99eadbf6 Author: djm@openbsd.org -Date: Tue Apr 30 06:23:51 2024 +0000 +Date: Tue Apr 1 23:23:20 2025 +0000 - upstream: fix home-directory extension implementation, it always + upstream: remove ability to enable DSA support. Actual code will be - returned the current user's home directory contrary to the spec. + g/c'd separately. ok deraadt@ - Patch from Jakub Jelen via GHPR477 + OpenBSD-Commit-ID: 2a032b75156c4d922e8343fa97ff6bc227f09819 + +commit 8460aaa4e1f8680f03cc5334556b9440b401f010 +Author: dtucker@openbsd.org +Date: Fri Mar 28 21:45:55 2025 +0000 + + upstream: Add TEST_SSH_SSHD_ENV to sshd lines here too. - OpenBSD-Commit-ID: 5afd775eab7f9cbe222d7fbae4c793de6c3b3d28 + OpenBSD-Regress-ID: 045f2c88b42d694b404db51c5de5eca20d748ff1 -commit 14e2b16bc67ffcc188906f65008667e22f73d103 -Author: djm@openbsd.org -Date: Tue Apr 30 06:16:55 2024 +0000 +commit 5e60f5937b9c33190b9d7614f72d85d4a9b38d3d +Author: dtucker@openbsd.org +Date: Fri Mar 28 06:04:07 2025 +0000 - upstream: flush stdout after writing "sftp>" prompt when not using + upstream: Pass "ControlMaster no" to ssh when invoked by scp & sftp. - editline. + If you have ControlMaster auto (or yes) in your config, and the + first connection you make is via scp or sftp, then you may get a + few unexpected options applied to it (eg ForwardX11 no), since sftp + and sftp explicitly disable those for reasons. These effects will + persist beyond the initial scp or sftp command. - From Alpine Linux via GHPR480 + This explicitly disables persistent session *creation* by scp and sftp. + It will not prevent them from using an existing session if one has + already been created. - OpenBSD-Commit-ID: 80bdc7ffe0358dc090eb9b93e6dedb2b087b24cd + From Github PR#557, ok djm@ kn@ + + OpenBSD-Commit-ID: 9dad7c737466837e0150c4318920f46d844770c4 -commit 2e69a724051488e3fb3cd11531c4b5bc1764945b -Author: djm@openbsd.org -Date: Tue Apr 30 05:53:03 2024 +0000 +commit bbd36869dfb4b770cc9e6a345c04a585a0955aec +Author: dtucker@openbsd.org +Date: Fri Mar 28 05:41:15 2025 +0000 - upstream: stricter validation of messaging socket fd number; disallow - - usage of stderr. Based on GHPR492 by RealHurrison + upstream: Set sshd environment variables during sshd test run too. - OpenBSD-Commit-ID: 73dbbe82ea16f73ce1d044d3232bc869ae2f2ce8 + OpenBSD-Regress-ID: 50cb325d92c390a2909662c901f6ac5d80b6f74d -commit da757b022bf18c6f7d04e685a10cd96ed00f83da -Author: djm@openbsd.org -Date: Tue Apr 30 05:45:56 2024 +0000 +commit 98f05b1484daddef2f56b79e24540523b5016143 +Author: dtucker@openbsd.org +Date: Fri Mar 28 05:36:24 2025 +0000 - upstream: add missing reserved fields to key constraint protocol + upstream: Add TEST_SSH_SSHD_ENV variable which is added to sshd's - documentation. + environment. Will be used in Portable to tweak behaviour of tcmalloc's + debugging. - from Wiktor Kwapisiewicz via GHPR487 + OpenBSD-Regress-ID: 67e38c3c4517ddb72c8a3549a3325a166d7bb6d6 + +commit 8cd9ed4df0eccc825eca0c45354a37332e125e38 +Author: dtucker@openbsd.org +Date: Fri Mar 28 05:33:30 2025 +0000 + + upstream: chown log directory in addition to log files. - OpenBSD-Commit-ID: 0dfb69998cfdb3fa00cbb0e7809e7d2f6126e3df + OpenBSD-Regress-ID: b520d54a0bbf2c6554413c798218bda26b385ad9 -commit 16d0b82fa08038f35f1b3630c70116979f49784f -Author: Damien Miller -Date: Tue Apr 30 12:39:34 2024 +1000 +commit e32de6bf4f3229d4838beb127de45eed1377ccc5 +Author: Darren Tucker +Date: Fri Mar 28 16:47:58 2025 +1100 - depend + Be explicit about environment variables for tests. + + This will make it easier to reproduce a test failure by cut-and-paste of + the corresponding line from the github log. -commit 66aaa678dbe59aa21d0d9d89a3596ecedde0254b -Author: djm@openbsd.org -Date: Tue Apr 30 02:14:10 2024 +0000 +commit 77a3e6ba47381547b3fe4b29223256f276fbd07e +Author: Darren Tucker +Date: Fri Mar 28 16:46:40 2025 +1100 - upstream: correctly restore sigprocmask around ppoll() reported + Add tcmalloc flags to TEST_SSH_SSHD_ENV. - by Tõivo Leedjärv; ok deraadt@ + This will get passed to sshd via test-exec.sh. + +commit a73890e340fbd6121251854b658a72d738b86c84 +Author: Darren Tucker +Date: Thu Mar 27 23:04:44 2025 +1100 + + Add PuTTY 0.81, 0.82 and 0.83 to tests. + +commit 90a28de0d49570324d1695c0b4686354ef3bcae0 +Author: Darren Tucker +Date: Thu Mar 27 22:30:40 2025 +1100 + + Include TCMALLOC_STACKTRACE_METHOD in output. - OpenBSD-Commit-ID: c0c0f89de5294a166578f071eade2501929c4686 + If TCMALLOC_STACKTRACE_METHOD happens to be set, include it in the debug + output to make reproducing test cases easier. -commit 80fb0eb21551aed3aebb009ab20aeffeb01e44e0 -Author: djm@openbsd.org -Date: Tue Apr 30 02:10:49 2024 +0000 +commit fd5a6bb6dd7657c4bd8cd0ee11d5c8ddf0d927b2 +Author: Darren Tucker +Date: Thu Mar 27 20:15:11 2025 +1100 - upstream: add explict check for server hostkey type against + Test with-linux-memlock-onfault in kitchensink. + +commit 22330711e2459c23d9736ee16e0e2ee0fcc30b9a +Author: Collin Funk +Date: Wed Mar 26 18:24:59 2025 -0700 + + Include fcntl.h so AT_FDCWD does not get redefined. + +commit 6c49e5f7dcaf886b4a702a6c003cae9dca04d3ea +Author: Daniil Tatianin +Date: Thu Feb 27 11:37:13 2025 +0300 + + Add support for locking memory on Linux - HostkeyAlgorithms. Allows HostkeyAlgorithms to disable implicit fallback from - certificate keys to plain keys. ok markus@ + Linux wakes up kcompactd threads in order to make more contiguous memory + available on the system, it does this by migrating live movable pages + (actively modifying live processes' page tables and constantly flooding + them with page invalidation IPIs, which can be up to millions per + second), which causes the process to become unresponsive for up to + seconds or even minutes in some severe cases. In case of sshd, we want + to always be able to connect to the system, even if it's under heavy + kcompactd load. - OpenBSD-Commit-ID: 364087e4a395ff9b2f42bf3aefdb2090bb23643a + Introduce an option to protect sshd and its children sessions from being + compacted by kcompactd (this works in cojunction with + compact_unevictable_allowed = 0). Note that we depend on MCL_ONFAULT + being available, which was introduced in linux 4.4. MCL_ONFAULT allows + the system to lock pages lazily, thus drastically reducing memory usage + of a locked process (without MCL_ONFAULT, every existing mapping in the + process is instantly write-faulted). -commit 5b28096d31ff7d80748fc845553a4aef5bb05d86 -Author: jsg@openbsd.org -Date: Tue Apr 23 13:34:50 2024 +0000 +commit fdc4853c5b1567934d43ab13282f03033cc21325 +Author: Daniil Tatianin +Date: Thu Feb 27 11:46:25 2025 +0300 - upstream: correct indentation; no functional change ok tb@ + platform: introduce a way to hook new session start - OpenBSD-Commit-ID: dd9702fd43de546bc6a3f4f025c74d6f3692a0d4 + Previously this was possible via post_fork_child, but ever since sshd + was split into multiple binaries, this is now no longer possible becase + of execv. -commit fd3cb8a82784e05f621dea5b56ac6f89bc53c067 -Author: semarie@openbsd.org -Date: Thu Apr 4 16:00:51 2024 +0000 +commit 1b311b6b17be81577514c38e8be4f5740d7df496 +Author: dtucker@openbsd.org +Date: Wed Mar 19 06:11:15 2025 +0000 - upstream: set right mode on ssh-agent at boot-time + upstream: Prevent theoretical NULL deref in throughlocal_sftp. - which sthen@ - ok deraadt@ + Coverity CID 405019, although at the moment it's not reachable. ok djm@ - OpenBSD-Commit-ID: 662b5056a2c6171563e1626f9c69f27862b5e7af + OpenBSD-Commit-ID: 630d46c1021b69fbb470e349976c70e9a48b7644 -commit 54343a260e3aa4bceca1852dde31cd08e2abd82b -Author: deraadt@openbsd.org -Date: Tue Apr 2 12:22:38 2024 +0000 +commit 96493ebd6ff48bbb802576e208794a26928569b0 +Author: Darren Tucker +Date: Wed Mar 19 17:35:10 2025 +1100 - upstream: Oops, incorrect hex conversion spotted by claudio. - - While here try to improve how it reads a bit better. Surprising the - regression tests didn't spot this error, maybe it fails to roundtrip the - values. - - OpenBSD-Commit-ID: 866cfcc1955aef8f3fc32da0b70c353a1b859f2e + Fix workflow syntax again. -commit ec78c31409590ad74efc194f886273ed080a545a -Author: deraadt@openbsd.org -Date: Tue Apr 2 10:02:08 2024 +0000 +commit 575c43fd4c44d376b1771c0fdaf4941021ba88c9 +Author: Darren Tucker +Date: Tue Mar 18 20:54:48 2025 +1100 - upstream: for parse_ipqos(), use strtonum() instead of mostly + Differentiate logfiles better. + +commit 8a1294638f3a47d46263ea574fa85c8e115ea893 +Author: Darren Tucker +Date: Tue Mar 18 20:27:46 2025 +1100 + + Fix another typo in workflow. + +commit bd9e6bbcc864b3e10c4e11f5aec1b3a5e3a89b55 +Author: Darren Tucker +Date: Tue Mar 18 18:16:12 2025 +1100 + + Fix syntax error in workflow. + +commit ce88a1bb4a2e6425752094f7a2eb4adfb0ca7971 +Author: Darren Tucker +Date: Tue Mar 18 18:13:14 2025 +1100 + + Identify each logfile while printing them. + +commit b58e429960c4791fc4e30bb7c70d1f77d538b546 +Author: djm@openbsd.org +Date: Tue Mar 18 04:53:14 2025 +0000 + + upstream: fix NULL dereference for Match conditions missing - idiomatic strtoul(), but wow it's so gross. ok djm + arguments, e.g. "Match user". Spotted by Coverity (CID 477813) - OpenBSD-Commit-ID: cec14a76af2eb7b225300c80fc0e21052be67b05 + OpenBSD-Commit-ID: 13584281cfa23b8ebc41f9d128a6b9464ae960d4 -commit 8176e1a6c2e6da9361a7abb6fbf6c23c299f495b -Author: deraadt@openbsd.org -Date: Tue Apr 2 09:56:58 2024 +0000 +commit 0ce5281f017c3ad7bdcc2bbd9745119a73e0cbb8 +Author: tb@openbsd.org +Date: Fri Mar 14 09:49:49 2025 +0000 - upstream: can shortcut by returning strtonum() value directly; ok + upstream: Fix EVP_CIPHER_CTX_ctrl() return checks - djm + While this API tries to translate negative return values (i.e. -1) to 0 + in BoringSSL and LibreSSL, it is still possible for it to return negative + values in prinicple. We even incorrectly document that -1 can be returned + while Boring and OpenSSL plead the Fifth. - OpenBSD-Commit-ID: 7bb2dd3d6d1f288dac14247d1de446e3d7ba8b8e + In OpenSSL 3 there are now code paths that explicitly return -1 and they + started shifting their return checks to <= 0 - of course they do this in + inconsistent and sometimes incorrect manner. While these paths aren't + reachable from ssh right now, who can really tell what happens in the two + hundred lines of inscrutable bloated mess this has become. + + So error check with <= 0 to ensure that we don't accidentally translate an + error to success. + + ok markus schwarze + + OpenBSD-Commit-ID: a855c833cf4ecfce43bedc761f26ad924f70483c -commit 9f543d7022a781f80bb696f9d73f1d1c6f9e31d6 -Author: deraadt@openbsd.org -Date: Tue Apr 2 09:52:14 2024 +0000 +commit 2e81100763d5885e500f065b04c16ed87ce74318 +Author: Darren Tucker +Date: Mon Mar 17 21:35:55 2025 +1100 - upstream: rewrite convtime() to use a isdigit-scanner and + Fix debug log path. + +commit 442a44970179d70ebb62bba792699eaec978a1db +Author: Darren Tucker +Date: Fri Mar 14 16:24:06 2025 +1100 + + Also lazily unmount workspace in case of straggers. + +commit 20427f6735fe5ddab31911ce5315adc71acf47d8 +Author: Darren Tucker +Date: Fri Mar 14 16:17:39 2025 +1100 + + Make sure upstream tests run on correct hardware. + +commit 91a2f70a56827ae31649baf17227b0914ac5aa36 +Author: Darren Tucker +Date: Fri Mar 14 13:47:27 2025 +1100 + + Add OpenBSD upstream test on obsdsnap-arm64. + +commit c20f7413525602b0ea786d8974d03a81f7ca2a92 +Author: Damien Miller +Date: Thu Mar 13 10:45:53 2025 +1100 + + rebuild .depend + +commit d47ef958b89c6fa809302d654009d3dfabe11b75 +Author: djm@openbsd.org +Date: Wed Mar 12 22:43:44 2025 +0000 + + upstream: remove assumption that the sshd_config and any configs - strtonum() instead of strange strtoul can might be fooled by garage - characters. passes regress/usr.bin/ssh/unittests/misc ok djm + included from it can fit in a (possibly enlarged) socket buffer, by having + the sshd listener mainloop actively manage sending the configuration to the + sshd-session subprocess. - OpenBSD-Commit-ID: 4b1ef826bb16047aea3f3bdcb385b72ffd450abc + work by markus@ w/ a little feedback from me; + ok me and committing on his behalf + + OpenBSD-Commit-ID: 8f54451483f64951853074adb76bc4f838eaf3ae -commit 8673137f780d8d9e4cda3c4605cb5d88d5cea271 -Author: claudio@openbsd.org -Date: Tue Apr 2 09:48:24 2024 +0000 +commit 9c90b563943c16418d737433ac478974b8761ee5 +Author: dtucker@openbsd.org +Date: Tue Mar 11 11:46:44 2025 +0000 - upstream: Remove unused ptr[3] char array in pkcs11_decode_hex. + upstream: Prime caches for DNS names needed for tests. - OK deraadt@ + When running the SSHFP tests, particularly on an ephemeral VM, the first + query or two can fail for some reason, presumably because something isn't + fully initialized or something. To work around this, issue queries for the + names we'll need before we need them. - OpenBSD-Commit-ID: 3d14433e39fd558f662d3b0431c4c555ef920481 + OpenBSD-Regress-ID: 900841133540e7dead253407db5a874a6ed09eca -commit c7fec708f331f108343d69e4d74c9a5d86d6cfe7 -Author: deraadt@openbsd.org -Date: Tue Apr 2 09:32:28 2024 +0000 +commit 10124eefe875a3e4e1cfb84ebe6a613ed3213b78 +Author: dtucker@openbsd.org +Date: Tue Mar 11 09:06:50 2025 +0000 - upstream: Replace non-idiomatic strtoul(, 16) to parse a region + upstream: Some dd's don't understand "1m", so handle seperately. - of 2-character hex sequences with a low-level replacement designed just for - the task. ok djm - - OpenBSD-Commit-ID: 67bab8b8a4329a19a0add5085eacd6f4cc215e85 + OpenBSD-Regress-ID: 1d983b27c96f28f69d3a288c19e8d8c58e1b2ee3 -commit 019a5f483b0f588da6270ec401d0b4bb35032f3f -Author: deraadt@openbsd.org -Date: Tue Apr 2 09:29:31 2024 +0000 +commit c21c8fc319376c2f5e0da166e9e89a97a245ae72 +Author: Darren Tucker +Date: Tue Mar 11 19:17:46 2025 +1100 - upstream: Use strtonum() instead of severely non-idomatic + Lazily unmount github workspace at end of workflow. - strtoul() In particular this will now reject trailing garbage, ie. - '12garbage'. ok djm + Sometimes when a test times out the workspace is still busy when we try + to unmount it, which leaves the runner unusable until it's cleaned up + manually. We try to unmount this in the first step, but that usually + doesn't work since it fails during setup before it starts our workflow. + Move it to the end and make it a lazy unmount so it hopefully works + eventually. + +commit 4bcbac742968f5086cfd4c570a51de25ef77931f +Author: dtucker@openbsd.org +Date: Tue Mar 11 07:50:20 2025 +0000 + + upstream: Add regress test for sftp resume. - OpenBSD-Commit-ID: c82d95e3ccbfedfc91a8041c2f8bf0cf987d1501 + OpenBSD-Regress-ID: 37f629b3014338fa23a85df1e1bb320ea12282e1 -commit 8231ca046fa39ea4eb99b79e0a6e09dec50ac952 -Author: deraadt@openbsd.org -Date: Mon Apr 1 15:50:17 2024 +0000 +commit e2c4f070b43a4fd7d59a9350e2fe78df605830b5 +Author: dtucker@openbsd.org +Date: Tue Mar 11 07:46:02 2025 +0000 - upstream: also create a relink kit for ssh-agent, since it is a + upstream: Use ssh binary instead of the (smaller) script when - long-running setgid program carrying keys with some (not very powerful) - communication channels. solution for testing the binary from dtucker. - agreement from djm. Will add it into /etc/rc in a few days. + preparing test data files since it's faster. - OpenBSD-Commit-ID: 2fe8d707ae35ba23c7916adcb818bb5b66837ba0 + OpenBSD-Regress-ID: 4215e42682fdb73e131e10645d4a1a23a91d64f5 -commit bf7bf50bd6a14e49c9c243cb8f4de31e555a5a2e -Author: deraadt@openbsd.org -Date: Mon Apr 1 15:48:16 2024 +0000 +commit 62f02e95ba5cda4649c482d30f4370e2360eb94d +Author: dtucker@openbsd.org +Date: Tue Mar 11 07:43:45 2025 +0000 - upstream: new-style relink kit for sshd. The old scheme created + upstream: Set up dbclient's known_hosts as it expects. - a Makefile by concatenating two Makefiles and was incredibly fragile. In the - new way a narrow-purposed install.sh script is created and shipped with the - objects. A recently commited /etc/rc script understands these files. + OpenBSD-Regress-ID: 9e0898e8423237ce5023be53787bb4062e0d0418 + +commit 395284bd52887dbaf7e78200c857d7f2d9ce398e +Author: dtucker@openbsd.org +Date: Tue Mar 11 07:43:03 2025 +0000 + + upstream: Use $DBCLIENT to access dbclient for consistency. - OpenBSD-Commit-ID: ef9341d5a50f0d33e3a6fbe995e92964bc7ef2d3 + OpenBSD-Regress-ID: 81e1b41e1ffc49aba1e6fcaeb6242f3b7875ea3c -commit 00e63688920905e326d8667cb47f17a156b6dc8f -Author: renmingshuai -Date: Fri Apr 12 10:20:49 2024 +0800 +commit 97e10c0005a784622c61cb4e8bb7858b410bbcc6 +Author: dtucker@openbsd.org +Date: Tue Mar 11 07:42:08 2025 +0000 - Shell syntax fix (leftover from a sync). + upstream: Check if dbclient supports SHA1 before trying SHA1-based - Signed-off-by: renmingshuai + KEX. + + Dropbear 2025.87 removed SHA1 support by default, which means + diffie-hellman-group14-sha1 is not available. Unfortunately there isn't a + flag to query supported KEX, so instead check MACs and if it doesn't have + SHA1 methods, assuming SHA1 based KEXes are likewise not available. Spotted + by anton@. + + OpenBSD-Regress-ID: acfa8e26c001cb18b9fb81a27271c3b51288d304 -commit 2eded551ba96e66bc3afbbcc883812c2eac02bd7 -Author: Darren Tucker -Date: Thu Apr 25 13:20:19 2024 +1000 +commit 29a5127f808d00aa539fd27d83a65c2c56179b0e +Author: dtucker@openbsd.org +Date: Tue Mar 11 07:48:51 2025 +0000 - Merge flags for OpenSSL 3.x versions. + upstream: Set highwater when resuming a "put". Prevents bogus "server - OpenSSL has moved to 3.4 which we don't currently accept. Based on - the OpenSSL versioning policy[0] it looks like all of the 3.x versions - should work with OpenSSH, so remove the distinction in configure and - accept all of them. + reordered acks" debug message. ok djm@ - [0] https://openssl.org/policies/general/versioning-policy.html + OpenBSD-Commit-ID: aa7f6d0fc2e893c8c278ea3e6e0974c2eca83f5d -commit 8673245918081c6d1dc7fb3733c8eb2c5a902c5e -Author: Darren Tucker -Date: Thu Apr 25 13:19:03 2024 +1000 +commit 6575859d7acb110acf408707f98ed9744ca7d692 +Author: dtucker@openbsd.org +Date: Mon Mar 3 06:54:37 2025 +0000 - Remove 9.6 branch from status page. + upstream: Test for %-token and env var expansion in SetEnv. + + OpenBSD-Regress-ID: bd6139a6177ac4afb29a0ce4afc23567b22ef9f9 -commit 70d43049747fa3c66cf876d52271859407cec2fa -Author: Darren Tucker -Date: Thu Apr 25 13:16:58 2024 +1000 +commit fd7ad8d7bf7dbdeb8f11a8b51aa9d31df1a17e52 +Author: dtucker@openbsd.org +Date: Sun Mar 2 07:41:06 2025 +0000 - Update LibreSSL and OpenSSL versions tested. + upstream: Also test User expansions when supplied via -l option and - Update LibreSSL versions to current releases (3.8.4 & 3.9.1). - Add newly-released OpenSSL 3.3.0, and add tests against the 3.1 and - 3.3 branches. + user@host. + + OpenBSD-Regress-ID: 56415859260b53ef0dd20f71225ba5fdf6320f50 -commit 88351eca17dcc55189991ba60e50819b6d4193c1 -Author: 90 -Date: Fri Apr 5 19:36:06 2024 +0100 +commit e6cfd783f1491b502db9322aa970822c63f1667d +Author: dtucker@openbsd.org +Date: Sat Mar 1 06:12:47 2025 +0000 - Fix missing header for systemd notification + upstream: Tests for User expansion of %-tokens and environment + + variables. + + OpenBSD-Regress-ID: 7ed21dd0e09fb1f3537b8b177f171018aa501628 -commit 08f579231cd38a1c657aaa6ddeb8ab57a1fd4f5c -Author: Damien Miller -Date: Wed Apr 3 14:40:32 2024 +1100 +commit 197e503b8e4b642ce0f405a5d65da4256fa96431 +Author: djm@openbsd.org +Date: Fri Dec 6 16:25:58 2024 +0000 - notify systemd on listen and reload + upstream: use glob(3) wildcards in AuthorizedKeys/PrincipalsFile - Standalone implementation that does not depend on libsystemd. - With assistance from Luca Boccassi, and feedback/testing from Colin - Watson. bz2641 + tests to exercise this feature; ok dtucker + + OpenBSD-Regress-ID: 7f7b19c0b05b1862cc6521ce61b2b301a3f9cc3b -commit 43e7c1c07cf6aae7f4394ca8ae91a3efc46514e2 -Author: Darren Tucker -Date: Sun Mar 31 21:51:57 2024 +1100 +commit 396202180180a4ac16788d469508a348789dafa1 +Author: djm@openbsd.org +Date: Fri Dec 6 10:37:42 2024 +0000 - Port changes from selfhosted to upstream tests. + upstream: implement attestation verification for ED25519 keys - Should get them working again. + OpenBSD-Regress-ID: c44fa5cdb434375a8b5545fdb4fc651061afca1f -commit 281ea25a44bff53eefb4af7bab7aa670b1f8b6b2 -Author: Darren Tucker -Date: Sat Mar 30 18:20:16 2024 +1100 +commit b49875428cda9c16c5bd52552100da2b419cda5f +Author: dtucker@openbsd.org +Date: Mon Mar 3 06:53:09 2025 +0000 - Check if OpenSSL implementation supports DSA. + upstream: Add %-token and environment variable expansion to SetEnv. + + feedback deraadt@ jmc@, nits and ok djm@ - If --enable/disable-dsa-keys is not specified, set based on what OpenSSL - supports. If specified as enabled, but not supported by OpenSSL error - out. ok djm@ + OpenBSD-Commit-ID: 2f6e5070481cb73e6f35fd1c6608c1eeff88a5c1 -commit 2d2c068de8d696fe3246f390b146197f51ea1e83 +commit b6bba67e6c31d268480773e4fed16d0a32b4218e Author: djm@openbsd.org -Date: Sat Mar 30 05:56:22 2024 +0000 +Date: Sun Mar 2 22:44:00 2025 +0000 - upstream: in OpenSSH private key format, correct type for subsequent + upstream: fix PerSourcePenalty incorrectly using "crash" penalty when - private keys in blob. From Jakub Jelen via GHPR430 + LoginGraceTime was exceeded. Reported by irwin AT princeton.edu via bz3797 - OpenBSD-Commit-ID: d17dbf47554de2d752061592f95b5d772baab50b + OpenBSD-Commit-ID: 1ba3e490a5a9451359618c550d995380af454d25 -commit c2c0bdd3e96b3ef66d77fccb85ff4962dc76caf0 -Author: Eero Häkkinen -Date: Sat Sep 16 00:55:08 2023 +0300 +commit 38d69fee1b06948f160d94abd07b6b297630d30a +Author: Damien Miller +Date: Sun Mar 2 22:06:53 2025 +1100 - Expose SSH_AUTH_INFO_0 always to PAM auth modules. + include __builtin_popcount replacement function - This changes SSH_AUTH_INFO_0 to be exposed to PAM auth modules also - when a password authentication method is in use and not only - when a keyboard-interactive authentication method is in use. + Some systems/compilers lack __builtin_popcount(), so replace it as + necessary. Reported by Dennis Clarke; ok dtucker@ -commit 02c5ad23124ae801cf248d99ea5068fc4331ca01 -Author: Darren Tucker -Date: Wed Mar 27 17:42:58 2024 +1100 +commit c94138d02a45dda5015f38f5a60b0bdde29019c1 +Author: djm@openbsd.org +Date: Sun Mar 2 11:03:13 2025 +0000 + + upstream: whitespace + + OpenBSD-Commit-ID: 1bd8953a37451ef7e0991f9fceec5e8005fe986a - Rearrange selfhosted VM scheduling. +commit 65d2c59628e68e166046efa69e76c1d395a8df6e +Author: dtucker@openbsd.org +Date: Sun Mar 2 07:02:49 2025 +0000 + + upstream: Make a copy of the user when handling ssh -l, so that - Instead of trying to infer the type of the self hosted tests in each of - the driver scripts (inconsistently...), set one of the following - variables to "true" in the workflow: + later during User token expansion we don't end up freeing a member of argv. + Spotted by anton@'s regress tests. - VM: tests run in a virtual machine. - EPHEMERAL: tests run on an ephemeral virtual machine. - PERSISTENT: tests run on a persistent virtual machine - REMOTE: tests run on a physical remote host. + OpenBSD-Commit-ID: 2f671a4f5726b66d123b88b1fdd1a90581339955 + +commit bd30cf784d6e825ef71592fb723c41d4f2fd407b +Author: dtucker@openbsd.org +Date: Sat Mar 1 06:11:26 2025 +0000 + + upstream: Allow %-token and environment variable expansion in User, - EPHEMERAL VMs can have multiple instances of any given VM can exist - simultaneously and are run by a runner pool. The other types have a - dedicated runner instance and can only run a single test at a time. + with the exception of %r and %C which are self-referential. Requested in + bz#3477, ok djm@, man page improvements jmc@ - Other settings: - SSHFS: We need to sshfs mount over the repo so the workflow can collect - build artifacts. This also implies the tests must be run over ssh. - DEBUG_ACTIONS: enable "set -x" in scripts for debugging. + OpenBSD-Commit-ID: caeb46251ee073662f6f5864c6f7b92d8ac80fa8 -commit cd8a72707c02615365d0851ac51063ab6bfe258f -Author: Damien Miller -Date: Sat Mar 30 16:05:59 2024 +1100 +commit 94f59dcfc57f95ae044f75c3ce544329c8956c35 +Author: Darren Tucker +Date: Sat Mar 1 10:28:59 2025 +1100 - add new token-based signing key for dtucker@ + Rebuild config files if Makefile changes. - Verified in person and via signature with old key. - Will remove old key in a bit. + This ensures paths are updated if they are changed by re-running configure. + Patch from rapier at psc.edu. -commit 8d0e46c1ddb5b7f0992591b0dc5d8aaa77cc9dba -Author: Alkaid -Date: Tue Mar 12 03:59:12 2024 -0700 +commit dfd9880585db1570656022f9fe1519df673f7b8a +Author: Darren Tucker +Date: Wed Feb 26 18:16:03 2025 +1100 - Fix OpenSSL ED25519 support detection + Check for le32toh, le64toh, htole64 individually. - Wrong function signature in configure.ac prevents openssh from enabling - the recently new support for ED25519 priv keys in PEM PKCS8 format. + It appears that at least some versions of endian.h in glibc do not have + the latter two, so check for and replace each one individually. + bz#3794, ok djm@ -commit 697359be9c23ee43618243cdbcc9c7981e766752 +commit cb99e8eb228df366af33f4fe88d7a9dd0dbf0756 Author: djm@openbsd.org -Date: Sat Mar 30 04:27:44 2024 +0000 +Date: Tue Feb 25 06:25:30 2025 +0000 - upstream: allow WAYLAND_DISPLAY to enable SSH_ASKPASS + upstream: ressurect fix for "match invalid-user" that got clobbered - From dkg via GHPR479; ok dtucker@ + by 1.423 - OpenBSD-Commit-ID: 1ac1f9c45da44eabbae89375393c662349239257 + OpenBSD-Commit-ID: d18bf0945976e0f3467d710d4bc8bdbe181c0567 -commit 7844705b0364574cc70b941be72036c2c2966363 -Author: dtucker@openbsd.org -Date: Fri Mar 29 10:40:07 2024 +0000 +commit 487cf4c18c123b66c1f3f733398cd37e6b2ab6ab +Author: deraadt@openbsd.org +Date: Fri Feb 21 18:22:41 2025 +0000 - upstream: Use egrep instead of grep -E. + upstream: Also prohibit , (comma) in hostnames, proposed by David - Some plaforms don't have the latter so this makes things easier - in -portable. + Leadbeater ok djm millert - OpenBSD-Regress-ID: ff82260eb0db1f11130200b25d820cf73753bbe3 + OpenBSD-Commit-ID: 2837fa31dc6e81976f510f0a259edaa559b20b07 -commit 22b2b6c555334bffdf357a2e4aa74308b03b83c3 -Author: dtucker@openbsd.org -Date: Tue Mar 26 08:09:16 2024 +0000 +commit 3bc6de98c830bd5207f6c371ba69c5874f06305b +Author: Damien Miller +Date: Mon Feb 24 17:27:50 2025 +1100 - upstream: test -h is the POSIXly way of testing for a symlink. Reduces + Try to fix github tcmalloc target failure - diff vs Portable. - - OpenBSD-Regress-ID: 6f31cd6e231e3b8c5c2ca0307573ccb7484bff7d + tcmalloc may, depending on the stacktrace generator it uses, create + pipe(2) fds during shared library initialisation. These will later + get clobbered by ssh/sshd calling closefrom() and chaos will ensue. + Tell tcmalloc to use an unwinder that doesn't pull this stuff. -commit edcff77f82c2bb2b5653b36f1e47274c5ef3e8be -Author: Darren Tucker -Date: Tue Mar 26 18:58:58 2024 +1100 +commit 922e54bbfe8c8479453693ef52350338f0c19124 +Author: Damien Miller +Date: Fri Feb 21 13:44:35 2025 +1100 - Fix name of OpenBSD upstream CI jobs. + cleanup last mention of ubuntu-20.04 -commit 861b084429940e024f1b6e9c2779eac95d7a45db -Author: Darren Tucker -Date: Tue Mar 26 18:55:33 2024 +1100 +commit bc4b3f6dc1738d389e5c9dcca8c56d7e153fee49 +Author: Damien Miller +Date: Fri Feb 21 13:44:13 2025 +1100 - Resync with upstream: ${} around DATAFILE. + prune gcc/clang versions to be tested + + Test only the oldest and latest versions of each -commit 63f248c7693e7f0a3b9a13d2980ac9a7e37f2aea -Author: djm@openbsd.org -Date: Mon Mar 25 19:28:09 2024 +0000 +commit 94b73755f931d592a612ef5cb998694643eab5ff +Author: Damien Miller +Date: Fri Feb 21 11:30:22 2025 +1100 - upstream: optional debugging + Update AWS-LC version number - OpenBSD-Regress-ID: b4852bf97ac8fb2e3530f2d5f999edd66058d7bc + Patch from Shubham Mittal bz bz3792 -commit 16e2ebe06a62f09d4877b769876d92d6008a896f -Author: dtucker@openbsd.org -Date: Mon Mar 25 06:05:42 2024 +0000 +commit 6887099fae6d9f3482e1075d034e9343dc413200 +Author: Damien Miller +Date: Fri Feb 21 11:22:34 2025 +1100 - upstream: Verify string returned from local shell command. + adjust workflows for ubuntu version transition - OpenBSD-Regress-ID: 5039bde24d33d809aebfa8d3ad7fe9053224e6f8 + remove workflows for unsupported compilers, add a few for additional + supported compilers, move some workflows to run on ubuntu-latest -commit b326f7a1f39ff31324cc3fe2735178fb474c04a4 -Author: dtucker@openbsd.org -Date: Mon Mar 25 03:30:31 2024 +0000 +commit 33bb47e6f74f2ca8093946e6f462d655a9ae46d3 +Author: Damien Miller +Date: Thu Feb 20 17:10:32 2025 +1100 - upstream: Improve shell portability: grep -q is not portable so - - redirect stdout, and use printf instead of relying on echo to do \n - substitution. Reduces diff vs Portable. + Add ubuntu-*-arm test runners + +commit a0c95fbb215b2168fa51b15906e2d6990d7fef6b +Author: Damien Miller +Date: Thu Feb 20 17:03:28 2025 +1100 + + remove ubuntu-20.04 Github action runners - Also resync somewhat with upstream. + ubuntu-20.04 is deprecated now, so migrate all its unique runners + to ubuntu-22.04. - OpenBSD-Regress-ID: 9ae876a8ec4c4725f1e9820a0667360ee2398337 + ok dtucker@ -commit dbf2e319f0c582613fa45a735ea3c242ce56946b -Author: dtucker@openbsd.org -Date: Mon Mar 25 02:07:08 2024 +0000 +commit 0cbeedba81b57c56379e1d202b9ccd3b72af7ddc +Author: Damien Miller +Date: Tue Feb 18 19:03:42 2025 +1100 - upstream: Save error code from SSH for use inside case statement, + openssh-9.9p2 + +commit 0832aac79517611dd4de93ad0a83577994d9c907 +Author: djm@openbsd.org +Date: Tue Feb 18 08:02:48 2025 +0000 + + upstream: Fix cases where error codes were not correctly set - from portable. In some shells, "case" will reset the value of $?, so save it - first. + Reported by the Qualys Security Advisory team. ok markus@ - OpenBSD-Regress-ID: da32e5be19299cb4f0f7de7f29c11257a62d6949 + OpenBSD-Commit-ID: 7bcd4ffe0fa1e27ff98d451fb9c22f5fae6e610d -commit d2c8c4fa7def4fb057ed05b3db57b62c810a26f6 -Author: dtucker@openbsd.org -Date: Mon Mar 25 01:40:47 2024 +0000 +commit 6ce00f0c2ecbb9f75023dbe627ee6460bcec78c2 +Author: djm@openbsd.org +Date: Tue Feb 18 08:02:12 2025 +0000 - upstream: Increase timeout. Resyncs with portable where some of + upstream: Don't reply to PING in preauth phase or during KEX - the test VMs are slow enough for this to matter. + Reported by the Qualys Security Advisory team. ok markus@ - OpenBSD-Regress-ID: 6a83a693602eb0312f06a4ad2cd6f40d99d24b26 + OpenBSD-Commit-ID: c656ac4abd1504389d1733d85152044b15830217 -commit 83621b63514a84791623db3efb59d38bc4bf9563 -Author: dtucker@openbsd.org -Date: Mon Mar 25 01:28:29 2024 +0000 +commit 9e5bd74a85192c00a842f63d7ab788713b4284c3 +Author: jmc@openbsd.org +Date: Sat Feb 15 06:48:56 2025 +0000 - upstream: In PuTTY interop test, don't assume the PuTTY major + upstream: - use \& when contructs like "e.g." end a line, to avoid - version is 0. Patch from cjwatson at debian.org via bz#3671. + double spacing - macro is Qq not Oq - OpenBSD-Regress-ID: 835ed03c1b04ad46be82e674495521f11b840191 + OpenBSD-Commit-ID: 17e5d2d7f288cc7fc536e3af252224525f9fb43a -commit 8a421b927700f3834b4d985778e252b8e3299f83 -Author: Darren Tucker -Date: Tue Mar 26 18:38:14 2024 +1100 +commit f519e71fb7a46314ae16e2a75490649dc0bd01a2 +Author: Damien Miller +Date: Sat Feb 15 13:12:40 2025 +1100 - Really mkdir /usr/local/etc in CI tests. + depend -commit 2946ed522c47ce045314533d426b4e379f745e59 -Author: Darren Tucker -Date: Tue Mar 26 17:19:09 2024 +1100 +commit 9131ac64b0ebe66dc1de9d44bf8d1bd64a24c350 +Author: djm@openbsd.org +Date: Sat Feb 15 01:52:07 2025 +0000 - Better short name for OpenBSD upstream CI jobs too. + upstream: add "Match version" support to ssh_config. Allows + + matching on the local version of OpenSSH, e.g. "Match version OpenSSH_10.*" + + ok markus@ + + OpenBSD-Commit-ID: c0cb504d0b9e43ccf12e68a544a7cd625e89758d -commit 18dbe8eff647aacb82d7e86b4ce63d5beee11f25 -Author: Darren Tucker -Date: Tue Mar 26 17:13:52 2024 +1100 +commit 192a20df00c8a56fe7d92ffa23d959c865d7fb9e +Author: djm@openbsd.org +Date: Sat Feb 15 01:50:47 2025 +0000 - Ensure /usr/local/etc exists before using in tests. + upstream: Add support for "Match sessiontype" to ssh_config. Allows + + matching on the type of session requested, either "shell" for interactive + sessions, "exec" for command execution sessions, "subsystem" for subsystem + requests, such as sftp, or "none" for transport/forwarding-only sessions. + + ok markus@ + + OpenBSD-Commit-ID: eff5c001aecb2283d36639cfb28c0935a8bfd468 -commit 5fc1085128e3348bb1b5ee4d955cc767b019b3ad -Author: Darren Tucker -Date: Tue Mar 26 16:50:46 2024 +1100 +commit caa3c0c77082888236b0b0c4feb3e6879731b3ba +Author: djm@openbsd.org +Date: Sat Feb 15 01:48:30 2025 +0000 - Be more specific about when to rerun workflows. + upstream: "Match command ..." support for ssh_config to allow + + matching on the remote command specified on the commandline. + + Also relaxes matching rules for `Match tagged` to allow + `Match tagged ""` to match an empty tag value. This also works + for command. + + ok markus@ + + OpenBSD-Commit-ID: 00dcfea425bf58d824bf5e3464cfc2409121b60d -commit 5516923e8ae3da0823fea0d7d28aa813627142c0 -Author: Darren Tucker -Date: Tue Mar 26 16:35:27 2024 +1100 +commit 38f6000e9851a00e2e4b8e1eb4ea6a243ef7e6a3 +Author: Damien Miller +Date: Tue Feb 11 10:32:26 2025 +1100 - Add short names for test jobs on github CI. + depend -commit dc37d2d2470b4a9cedcee9ac926b7362214e3305 -Author: Darren Tucker -Date: Tue Mar 26 16:26:14 2024 +1100 +commit aa1409e7a0a5605f0127651a3ba5a348666325bc +Author: djm@openbsd.org +Date: Mon Feb 10 23:19:26 2025 +0000 - If we're using xpg4's id, remember to pass args. + upstream: include arguments the command was invoked with, and + + operating system name, version and architecture in startup debugging output; + ok dtucker + + OpenBSD-Commit-ID: 2a509d319aaf31a6bf9998e1842832883fbc3edd -commit fe169487937780392b23d3ff3c00e5898c10f784 -Author: dtucker@openbsd.org -Date: Tue Mar 26 01:23:11 2024 +0000 +commit 857ac20f5fe19f183defba5dbf4b7d9e6400230c +Author: djm@openbsd.org +Date: Mon Feb 10 23:16:51 2025 +0000 - upstream: Import regenerated moduli. + upstream: include line number in Match debug messages, makes it a + + little easier to see what's going on - OpenBSD-Commit-ID: ad3d1486d105b008c93e952d158e5af4d9d4c531 + OpenBSD-Commit-ID: 1fcf4aa2ee667711b9497ded0fa52d757c69b1df -commit 151146f03b490d19145cd421763aa7d42f5c50e2 -Author: job@openbsd.org -Date: Thu Mar 14 06:23:14 2024 +0000 +commit af49d474e481d2d78b2f06b06a06b0b37629358e +Author: djm@openbsd.org +Date: Mon Feb 10 23:00:29 2025 +0000 - upstream: Clarify how literal IPv6 addresses can be used in -J mode + upstream: fix "Match invalid-user" from incorrectly being activated - OK djm@ + in initial configuration pass when no other predicates were present on the + match line - OpenBSD-Commit-ID: 524ddae97746b3563ad4a887dfd0a6e6ba114c50 + OpenBSD-Commit-ID: 02703b4bd207fafd03788bc4e7774bf80be6c9a8 -commit 0d5bdc87a675271862b67eb6a9fb13a202fb4894 -Author: Darren Tucker -Date: Mon Mar 25 16:14:21 2024 +1100 +commit 1c67bae3f5834e48ded71c406f2039dea6e536db +Author: schwarze@openbsd.org +Date: Sun Feb 9 18:24:08 2025 +0000 - Add Mac OS X 14 test targets. + upstream: In a section 1 manual, use the plain English words + + "standard output" rather than the overly technical abbreviation "stdout" - we + are not talking about a device file or a FILE * object here. Issue reported + by on the groff mailing list. + + OpenBSD-Commit-ID: a0816999f970e6159523bed8484f62c42ec93109 -commit 2d7964a03e1f50a48040ec6912c0a956df909d21 -Author: Darren Tucker -Date: Mon Mar 25 14:05:40 2024 +1100 +commit 85b3d68dd931416ede657f371f1d60cdc3a66f34 +Author: dtucker@openbsd.org +Date: Fri Jan 17 00:09:41 2025 +0000 - Move xpg4 'id' handling into test-exec.sh. + upstream: Fix debug logging of user specific delay. Patch from + + Achim Leitner (fjl5) via github PR#552. - Handle replacement of 'id' the same way as we do other Portable specific - replacements in test-exec.sh. This brings percent.sh back into sync - with upstream. + OpenBSD-Commit-ID: 834a869ed9b15058d3c1ef0cd75402ef989255d8 -commit 75d1d49ed10d978171cdafad28bdbffdbd48f41e -Author: Darren Tucker -Date: Mon Mar 25 10:38:03 2024 +1100 +commit e4e5b06fdf4532705669c0ae944b364022d16b9d +Author: dtucker@openbsd.org +Date: Thu Jan 16 06:37:10 2025 +0000 - Update branches shown on ci-status to 9.7 and 9.6. + upstream: Call log_init in sshd-auth and sshd-session immediately + + after parsing the config file so that any log settings set in the config file + take effect immediately. Move version banners to immediately after that, and + make them distinct per binary. ok djm@ + + OpenBSD-Commit-ID: acf3d090638edf9b6e6f78eed96b537fe671f0f5 -commit f9193f03db0029fc9c31fbdb5c66a2737446bd8f -Author: Darren Tucker -Date: Mon Mar 25 09:28:02 2024 +1100 +commit 0643994b20f2cc54bca80842a984b3052ff1a6a9 +Author: dtucker@openbsd.org +Date: Wed Jan 15 22:23:13 2025 +0000 - Improve detection of -fzero-call-used-regs=used. + upstream: Use strprefix helper when processing sshd -C test args - Should better detect problems with gcc 13 on m68k. bz#3673 from Colin - Watson via bz#3673 and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110934 + instead of counting bytes by hand. ok djm@ - Signed-off-by: Darren Tucker + OpenBSD-Commit-ID: 2866d369d96fe04bf76112260ac37e489f98a9a9 -commit 86bdd3853f4d32c85e295e6216a2fe0953ad93f0 +commit 66efd0fbb6b8b95f8a520f2cdf8ede14e62b30b3 Author: Damien Miller -Date: Mon Mar 11 16:20:49 2024 +1100 +Date: Thu Feb 6 09:38:09 2025 +1100 - version number in README + add support for AWS-LC (AWS libcrypto) + + Patch from Shubham Mittal via bz3784; ok dtucker -commit 282721418e6465bc39ccfd39bb0133e670ee4423 -Author: Damien Miller -Date: Mon Mar 11 16:20:08 2024 +1100 +commit 826483d51a9fee60703298bbf839d9ce37943474 +Author: Tim Rice +Date: Mon Dec 16 15:36:54 2024 -0800 - crank RPM spec versions + fix old typo (s/SYSVINITSTOPT/SYSVINITSTOP/) -commit 3876a3bbd2ca84d23ba20f8b69ba83270c04ce3a -Author: djm@openbsd.org -Date: Mon Mar 11 04:59:47 2024 +0000 +commit 1a8ce460f1d0c3f7304edba0733783b57b430e21 +Author: dtucker@openbsd.org +Date: Thu Dec 12 09:09:09 2024 +0000 - upstream: openssh-9.7 + upstream: Plug leak on error path, spotted by Coverity. ok djm@ - OpenBSD-Commit-ID: 618ececf58b8cdae016b149787af06240f7b0cbc + OpenBSD-Commit-ID: b1859959374b4709569760cae0866d22a16606d3 -commit 8fc109cc614954a8eb2738c48c0db36a62af9a06 -Author: Darren Tucker -Date: Mon Mar 11 12:59:26 2024 +1100 +commit 924f996144fc0ae1a659fadcfc2237d1ae935fc4 +Author: Xavier Hsinyuan +Date: Mon Dec 9 11:21:05 2024 +0800 - Test against current OpenSSL and LibreSSL releases. + Add $(srcdir) for standalone sk-libfido2 make target. - Add LibreSSL 3.9.0, bump older branches to their respective current - releases. + Fix out-of-tree build failure due to incorrect path for `sk-usbhid.c`. -commit 26b09b45fec7b88ba09042c09be4157e58e231e2 -Author: Damien Miller -Date: Sun Mar 10 16:24:57 2024 +1100 +commit bbc9c18e84de29c83fa03e69290979fcca54a2b2 +Author: djm@openbsd.org +Date: Sat Dec 7 10:12:19 2024 +0000 - quote regexes used to test for algorithm support + upstream: replace bespoke logging of MaxSessions enforcement with + + new ratelimited logging infrastructure. + + Add ratelimits to logging of connections dropped by PerSourcePenalties + + ok dtucker - Fixes test failures on Solaris 8 reported by Tom G. Christensen + OpenBSD-Commit-ID: f22fe7c39607e4361aadf95e33773ffd68c59489 -commit a6a740a4948d10a622b505135bb485c10f21db5e +commit 5a6ddf946cf105189c2c99a04f86ce95edc55fc5 Author: djm@openbsd.org -Date: Sat Mar 9 05:12:13 2024 +0000 +Date: Sat Dec 7 10:05:36 2024 +0000 - upstream: avoid logging in signal handler by converting mainloop to + upstream: add infrastructure for ratelimited logging; feedback/ok - ppoll() bz3670, reported by Ben Hamilton; ok dtucker@ + dtucker - OpenBSD-Commit-ID: e58f18042b86425405ca09e6e9d7dfa1df9f5f7f + OpenBSD-Commit-ID: 18a83e5ac09d59aaf1e834fd6b796db89dd842e7 -commit cd82f7526e0481720567ae41db7849ab1c27e27b +commit 85f0c1e75e8f6c5d83b8070918ee2f6ab16d403e Author: djm@openbsd.org -Date: Fri Mar 8 22:16:32 2024 +0000 +Date: Fri Dec 6 16:24:27 2024 +0000 - upstream: skip more whitespace, fixes find-principals on + upstream: allow glob(3) patterns for sshd_config AuthorizedKeysFile - allowed_signers files with blank lines; reported by Wiktor Kwapisiewicz + and AuthorizedPrincipalsFile directives; bz2755 ok dtucker - OpenBSD-Commit-ID: b3a22a2afd753d70766f34bc7f309c03706b5298 + OpenBSD-Commit-ID: 3e3e05a17fca39bba78b993a07b44664519adf7f -commit 2f9d2af5cb19905d87f37d1e11c9f035ac5daf3b -Author: dtucker@openbsd.org -Date: Fri Mar 8 11:34:10 2024 +0000 +commit 9a9ffee6e10bcd039f1f9385599577441ebe542a +Author: djm@openbsd.org +Date: Fri Dec 6 16:21:48 2024 +0000 - upstream: Invoke ProxyCommand that uses stderr redirection via + upstream: support VersionAddendum in the client, mirroring the - $TEST_SHELL. Fixes test when run by a user whose login shell is tcsh. - Found by vinschen at redhat.com. + option of the same name in the server; bz2745 ok dtucker@ - OpenBSD-Regress-ID: f68d79e7f00caa8d216ebe00ee5f0adbb944062a + OpenBSD-Commit-ID: 6ff7905b3f9806649bde750515786553fb89cdf4 -commit 9b3f0beb4007a7e01dfedabb429097fb593deae6 -Author: Darren Tucker -Date: Thu Mar 7 17:18:14 2024 +1100 +commit 41ab0ccecd68232e196efae5e224b31ca104c423 +Author: djm@openbsd.org +Date: Fri Dec 6 16:02:12 2024 +0000 - Prefer openssl binary from --with-ssl-dir directory. + upstream: clarify encoding of options/extensions; bz2389 - Use openssl in the directory specified by --with-ssl-dir as long - as it's functional. Reported by The Doctor. + OpenBSD-Commit-ID: c4e92356d44dfe6d0a4416deecb33d1d1eba016c -commit c47e1c9c7911f38b2fc2fb01b1f6ae3a3121a838 +commit 5488810359f0fd91e2f7b919c70a3798e46376cb Author: djm@openbsd.org -Date: Wed Mar 6 02:59:59 2024 +0000 +Date: Fri Dec 6 15:17:15 2024 +0000 - upstream: fix memory leak in mux proxy mode when requesting forwarding. + upstream: ignore SIGPIPE here; some downstreams have had this for - found by RASU JSC, reported by Maks Mishin in GHPR#467 + years... - OpenBSD-Commit-ID: 97d96a166b1ad4b8d229864a553e3e56d3116860 + OpenBSD-Commit-ID: 73674ee4f8ceb8fc9cb8de71d8ddea0c721eb035 -commit 242742827fea4508e68097c128e802edc79addb5 +commit 4389a792d9078212366eba124a3eed36e009d09e Author: djm@openbsd.org -Date: Wed Mar 6 00:31:04 2024 +0000 +Date: Fri Dec 6 15:12:56 2024 +0000 - upstream: wrap a few PKCS#11-specific bits in ENABLE_PKCS11 + upstream: sync -o option lists with ssh.1; requested jmc@ - OpenBSD-Commit-ID: 463e4a69eef3426a43a2b922c4e7b2011885d923 + OpenBSD-Commit-ID: a7ac295b444da7b2ca7a33a52370594f6897f6bb -commit d52b6509210e2043f33e5a1de58dd4a0d5d48c2a -Author: Damien Miller -Date: Wed Mar 6 11:31:36 2024 +1100 +commit 6b9cd095565ddc5402d5096dce248fa0521dbda3 +Author: Fabio Pedretti +Date: Mon Oct 16 17:12:24 2023 +0200 - disable RSA tests when algorithm is not supported + Remove ancient RHL 6.x config in RPM spec. - Unbreaks "make test" when compiled --without-openssl. + It looks like build6x options were intended for RHL 6.x + (the Red Hat distro predating Fedora, not RHEL), but were + then applied to RHEL. - Similar treatment to how we do DSA and ECDSA. + Completely remove support for this ancient configuration. + + Successfully built, installed and run on RHEL 6. This also + remove a build warning about deprecation of PreReq. -commit 668d270a6c77e8b5a1da26ecad2e6de9f62c8fe4 -Author: Damien Miller -Date: Wed Mar 6 10:33:20 2024 +1100 +commit 5cacfa798f92b707491375fed748d1d1bcb33ec9 +Author: Darren Tucker +Date: Fri Dec 6 23:54:45 2024 +1100 - add a --without-retpoline configure option + Add new hardware-backed signing key for myself. - discussed with deraadt and dtucker a while ago + Retire old non-hardware based signing key. -commit 3deb501f86fc47e175ef6a3eaba9b9846a80d444 -Author: djm@openbsd.org -Date: Mon Mar 4 04:13:18 2024 +0000 +commit f129b6ee1d4361799e65307216e3a4d5544356b7 +Author: Jonas 'Sortie' Termansen +Date: Sat Nov 2 22:05:45 2024 +0100 - upstream: fix leak of CanonicalizePermittedCNAMEs on error path; + Fix configure implicit declaration and format warnings. + +commit 11a5e5179077f73c2d45bcdf3f60153ae3f17815 +Author: dtucker@openbsd.org +Date: Fri Dec 6 07:05:54 2024 +0000 + + upstream: Expand $SSH to absolute path if it's not already. - spotted by Coverity (CID 438039) + Prevents problem later in increase_datafile_size if ssh is not in + the path. Patch from quaresmajose via GHPR#510. - OpenBSD-Commit-ID: 208839699939721f452a4418afc028a9f9d3d8af + OpenBSD-Regress-ID: 2670a66af8b827410ca7139f0a89f4501cece77b -commit 65a44a8a4f7d902a64d4e60eda84384b2e2a24a2 -Author: djm@openbsd.org -Date: Mon Mar 4 02:16:11 2024 +0000 +commit dc2ef8f0944a4ff7ba19e52fd17b4654e6bd9b93 +Author: dtucker@openbsd.org +Date: Fri Dec 6 06:55:28 2024 +0000 + + upstream: Change "login again" to "log in again" + + in password change message. From ThinLinc-Zeijlon via github PR#532. + + OpenBSD-Commit-ID: fea5e9bc04caf613a118c419f16863733b340cf1 - upstream: Separate parsing of string array options from applying them +commit 8252f346eb21cd6b30816f905b7d94f10962373e +Author: naddy@openbsd.org +Date: Thu Dec 5 22:45:03 2024 +0000 + + upstream: catch up documentation: AES-GCM is preferred to AES-CTR - to the active configuration. This fixes the config parser from erroneously - rejecting cases like: + OpenBSD-Commit-ID: 63360924b6834507fe70020edb936f5075043a9e + +commit 9a2f4c75081769bd45eba2bf3fab0a32b25f1879 +Author: Darren Tucker +Date: Fri Dec 6 17:56:17 2024 +1100 + + Change text from "login to" to "log in to". - AuthenticationMethods password - Match User ivy - AuthenticationMethods any + From ThinLinc-Zeijlon via GHPR#532. + +commit 24dcf368d816b06136a02845ebd0c7846bf18927 +Author: Xavier Hsinyuan +Date: Fri Dec 6 11:56:34 2024 +0800 + + Fix configure message typo in sk-libfido2 standalone. + +commit 1a0cac2f3411a22d69ae6918eff48456b805e73b +Author: Alexander Kanavin +Date: Thu Dec 5 16:26:46 2024 +0100 + + Skip 2038 key expiry test on 64 bit time_t systems. - bz3657 ok markus@ + This allows testing Y2038 with system time set to after that (i.e. 2040), + so that actual Y2038 issues can be exposed, and not masked by key expiry + errors. - OpenBSD-Commit-ID: 7f196cba634c2a3dba115f3fac3c4635a2199491 + Signed-off-by: Alexander Kanavin -commit 6886e1b1f55c90942e4e6deed930f8ac32e0f938 +commit 6b4611dc1232c5d2c8e43201f580f19aab320c87 Author: Darren Tucker -Date: Thu Feb 22 17:59:35 2024 +1100 +Date: Fri Dec 6 01:45:52 2024 +1100 + + Skip 64bit expiry time test on 32bit time_t. + +commit c9b7866a7dc5e6c30f5aa9d22dd0bbafda0d496f +Author: dtucker@openbsd.org +Date: Thu Dec 5 14:28:39 2024 +0000 - Add nbsd10 test target. + upstream: Add key expiry test in the 64bit time_t range for additional + + coverage. From Alexander Kanavin via bz#3684. + + OpenBSD-Regress-ID: bdf6eb3c2421f2e1e11483d03b34c7931d1bccf7 -commit d86bf8a3f6ea4fa7887406c2aa9959db71fa41be +commit 790c913b5fc6ee93ae14793443dc85a0f574b7eb Author: Damien Miller -Date: Thu Feb 22 12:06:10 2024 +1100 +Date: Thu Dec 5 19:24:56 2024 +1100 - more descriptive configure test name + typo -commit 9ee335aacc9f5bdc4cc2c19fafb45e27be7d234e -Author: djm@openbsd.org -Date: Wed Feb 21 06:17:29 2024 +0000 +commit d23a23aaeeabc228792e3fd7eb5f2fa6ae13c482 +Author: Damien Miller +Date: Thu Dec 5 08:47:02 2024 +1100 - upstream: explain arguments of internal-sftp GHPR#454 from Niklas + add a Makefile target for ssh-verify-attestation - Hambüchen - MIME-Version: 1.0 - Content-Type: text/plain; charset=UTF-8 - Content-Transfer-Encoding: 8bit + Not built by default, but easier than doing it by hand + +commit d0ac63d0f8b5f778d5fd326701ef4489bc27635e +Author: dtucker@openbsd.org +Date: Thu Dec 5 06:49:26 2024 +0000 + + upstream: De-magic the x11 base port number into a define. ok djm@ - OpenBSD-Commit-ID: 0335d641ae6b5b6201b9ffd5dd06345ebbd0a3f3 + OpenBSD-Commit-ID: 23b85ca9d222cb739b9c33ee5e4d6ac9fdeecbfa -commit d1164cb1001dd208fee88aaa9b43d5e6fd917274 -Author: djm@openbsd.org -Date: Wed Feb 21 06:06:43 2024 +0000 +commit 9998c93d57bf0f1df2bc93e0bc2d8112c6f8c720 +Author: dtucker@openbsd.org +Date: Thu Dec 5 06:47:00 2024 +0000 - upstream: clarify permissions requirements for ChrootDirectory Part + upstream: Prevent integer overflow in x11 port handling. These are - of GHPR#454 from Niklas Hambüchen - MIME-Version: 1.0 - Content-Type: text/plain; charset=UTF-8 - Content-Transfer-Encoding: 8bit + theoretically possible if the admin misconfigures X11DisplayOffset or the + user misconfigures their own $DISPLAY, but don't happen in normal operation. + From Suhov Roman via bz#3730, ok djm@ - OpenBSD-Commit-ID: d37bc8786317a11649c62ff5e2936441186ef7a0 + OpenBSD-Commit-ID: e9e3860f1a19b862ccf07dc8ecbe8f1e1034f4ed -commit d410e17d186552d0717f18217d0d049486754365 +commit 8c9ee046d40e4254c6c1711783ea11027b72c3e9 Author: djm@openbsd.org -Date: Wed Feb 21 06:05:06 2024 +0000 +Date: Wed Dec 4 16:42:49 2024 +0000 - upstream: .Cm for a keyword. Part of GHPR#454 from Niklas Hambüchen + upstream: add a work-in-progress tool to verify FIDO attestation - OpenBSD-Commit-ID: d59c52559f926fa82859035d79749fbb4a3ce18a + blobs that ssh-keygen can write when enrolling FIDO keys. + + OpenBSD-Regress-ID: 6c97bf3f46e48866677ad69f54b77683eb92437f -commit ab73f9678ebf06b32d6361b88b50b42775e0565b -Author: djm@openbsd.org -Date: Wed Feb 21 06:01:13 2024 +0000 +commit 50c640d874d0246dd0a0d949398c3d7f757c716a +Author: dtucker@openbsd.org +Date: Wed Dec 4 10:51:13 2024 +0000 - upstream: fix typo in match directive predicate (s/tagged/tag) GHPR#462 + upstream: Don't assume existence of SK provider in test. Patch from - from Tobias Manske + balu.gajjala at gmail via bz#3402. - OpenBSD-Commit-ID: 05b23b772677d48aa82eefd7ebebd369ae758908 + OpenBSD-Regress-ID: d571932016d07d135b54433d07520b9e1901db43 -commit 9844aa2521ccfb1a2d73745680327b79e0574445 +commit 73d782693144262570d3585b62f16b183170c014 Author: djm@openbsd.org -Date: Wed Feb 21 05:57:34 2024 +0000 +Date: Wed Dec 4 14:37:55 2024 +0000 - upstream: fix proxy multiplexing mode, broken when keystroke timing + upstream: sync the list of options accepted by -o with ssh_config.5 - obfuscation was added. GHPR#463 from montag451 + prompted by bz3455 - OpenBSD-Commit-ID: 4e412d59b3f557d431f1d81c715a3bc0491cc677 + OpenBSD-Commit-ID: 0ecbfa70aea6c769bcc259defe07182edf461f57 -commit ee6d932acb532f80b11bb7cf161668c70ec8a117 +commit 6993d9f0959534b0b7d52e17b95e9e79fb0b3d0a Author: djm@openbsd.org -Date: Tue Feb 20 04:10:03 2024 +0000 +Date: Wed Dec 4 14:24:20 2024 +0000 - upstream: don't append a gratuitous space to the end of subsystem + upstream: don't screw up ssh-keygen -l output when the file - arguments; bz3667 + contains CR characters; GHPR236 bz3385, fix from Dmitry Belyavskiy - OpenBSD-Commit-ID: e11023aeb3f30b77a674e37b8292c862926d5dc6 + OpenBSD-Commit-ID: e458cf6b0adcea5b69ef4c7ba38e590841d02ef4 -commit e27f032aa8fcbae9b2e7c451baaf4b8ac6fa3d45 -Author: dtucker@openbsd.org -Date: Mon Feb 19 09:25:52 2024 +0000 +commit c0b03c2534946fc114880092177aa4a3683ced2d +Author: jsg@openbsd.org +Date: Tue Dec 3 22:30:03 2024 +0000 - upstream: Always define puttysetup function. + upstream: spelling; ok djm@ - OpenBSD-Regress-ID: b4c0ccfa4006a1bc5dfd99ccf21c854d3ce2aee0 + OpenBSD-Commit-ID: c8ff3f70020451eef214e598117b7ce1a29853ef -commit 84046f9991abef5f46b040b10cf3d494f933a17b +commit 97eb247f40167f44324e88a537d5b4fe771a63b2 Author: dtucker@openbsd.org -Date: Fri Feb 9 08:56:59 2024 +0000 +Date: Tue Dec 3 16:27:53 2024 +0000 - upstream: Exapnd PuTTY test coverage. + upstream: Remove fallback to compiled-in gropup for dhgex when the - Expand the set of ciphers, MACs and KEX methods in the PuTTY interop - tests. + moduli file exists, but does not contain moduli within the client-requested + range. The fallback behaviour remains for the case where the moduli file does + not exist (typically, running tests prior to installing). From bz#2793, based + in part on patch from Joe Testa, ok djm@ - OpenBSD-Regress-ID: dd28d97d48efe7329a396d0d505ee2907bf7fc57 + OpenBSD-Commit-ID: b1a8c5dbbedf249b42474679ebaf14db7332b1ab -commit bbf541ee2afe07b08a8b56fa0dc6f38fcfceef2a -Author: dtucker@openbsd.org -Date: Fri Feb 9 08:47:42 2024 +0000 +commit 30c746265ebde29806dba77c92fb1fd3803cbf5c +Author: tb@openbsd.org +Date: Tue Dec 3 15:53:51 2024 +0000 - upstream: Factor out PuTTY setup. + upstream: Remove redundant field of definition check - Factor out PuTTY and call only when needed. + This will allow us to get rid of EC_GROUP_method_of() in the near future. - This allows us to avoid PuTTY key setup when it's not needed, which - speeds up the overall test run by a couple of percent. + ok djm - OpenBSD-Regress-ID: c25eaccc3c91bc874400f7c85ce40e9032358c1c + OpenBSD-Commit-ID: b4a3d2e00990cf5c2ec6881c21ddca67327c2df8 -commit d31c21c57fb4245271680a1e5043cf6470a96766 -Author: naddy@openbsd.org -Date: Sat Feb 10 11:28:52 2024 +0000 +commit eaa1744f34c30740328fd0a0d84b5f2f9e6918c1 +Author: Damien Miller +Date: Thu Dec 5 00:59:19 2024 +1100 - upstream: clean sshd random relinking kit; ok miod@ + don't ignore changes in regress Makefiles - OpenBSD-Commit-ID: 509bb19bb9762a4b3b589af98bac2e730541b6d4 + reported by Torben Hansen in bz2880 -commit 4dbc5a363ff53a2fcecf6bc3bcc038badc12f118 -Author: djm@openbsd.org -Date: Fri Feb 2 00:13:34 2024 +0000 +commit 66e986880b2472fefaad781f10113b138b65ff27 +Author: Damien Miller +Date: Thu Dec 5 00:01:33 2024 +1100 - upstream: whitespace + Support systemd-style socket activation in agent - OpenBSD-Commit-ID: b24680bc755b621ea801ff8edf6f0f02b68edae1 - -commit efde85dda2130272af24cc346f6c3cd326182ff1 -Author: Darren Tucker -Date: Mon Feb 19 17:29:31 2024 +1100 - - Improve error message for OpenSSL header check. + Adds support for systemd LISTEN_PID/LISTEN_FDS socket activation to + ssh-agent. Activated when these environment variables are set and + the agent is started with the -d or -D option and no socket path + is set. - bz#3668, ok djm@ - -commit cbbdf868bce431a59e2fa36ca244d5739429408d -Author: Darren Tucker -Date: Wed Feb 7 13:45:02 2024 +1100 - - Interop test against PuTTY snapshot and releases. + Based on GHPR502 by Daniel Kahn Gillmor, ok dtucker -commit 91898bf786b0f149f962c4c96c08a46f29888c10 +commit 9b57c099f57152e6c94f633c114f544087f4bdaa Author: Darren Tucker -Date: Tue Feb 6 16:21:05 2024 +1100 +Date: Wed Dec 4 21:36:01 2024 +1100 - Put privsep dir on OS X on /usr/local. + Update readme files to better reflect reality. - On some runners we can't create /var/empty, so put it some place we can - write. Should fix test breakage on Max OS X 11. + Prompted by bz#3738, ok djm@. -commit be5ed8ebed8388c5056bfde4688308cc873c18b9 -Author: Darren Tucker -Date: Tue Feb 6 11:19:42 2024 +1100 +commit ffa885db1b960451d426455045d2f51288e48ee8 +Author: dtucker@openbsd.org +Date: Tue Dec 3 14:12:47 2024 +0000 - Add --disable-fd-passing option. + upstream: Improve description of KbdInteractiveAuthentication. - .. and enable for the minix3 test VM. This will cause it to more reliably - skip tests that need FD passing and should fix the current test breakage. + Based on bz#3658, fixes jmc@ ok markus@ djm@. + + OpenBSD-Commit-ID: 9fadb56b9afed554d501acbba911c685acd6ffc2 -commit 0f6a8a0d0a518fd78c4cbebfdac990a57a1c4e41 -Author: Darren Tucker -Date: Tue Feb 6 11:18:44 2024 +1100 +commit b460f82a67795bba37c6cc6c78f788e5b435b4cb +Author: Jonas 'Sortie' Termansen +Date: Sat Nov 2 17:53:23 2024 +0100 - Use "skip" function instead doing it ourselves. + Inherit DESTDIR from the environment. + + autoconf packages conventionally inherit the DESTDIR variable from the + environment. -commit 3ad669f81aabbd2ba9fbd472903f680f598e1e99 -Author: Damien Miller -Date: Thu Feb 1 14:01:18 2024 +1100 +commit 9da7fa7c7464df241ae5d17da94e4ebed9013719 +Author: Jonas 'Sortie' Termansen +Date: Sat Nov 2 22:10:39 2024 +0100 - ignore some vim droppings + Define u_short and u_long if needed. -commit c283f29d23611a06bbee06bcf458f2fffad721d9 +commit d3a7ff7cecbc23cc37044bdf02e7118d05bf3c35 Author: djm@openbsd.org -Date: Thu Feb 1 02:37:33 2024 +0000 +Date: Tue Dec 3 08:31:49 2024 +0000 - upstream: whitespace + upstream: support FIDO tokens that return no attestation data, e.g. + + recent WinHello. From Michael Braun via GHPR542 - OpenBSD-Commit-ID: bf9e4a1049562ee4322684fbdce07142f04fdbb7 + OpenBSD-Commit-ID: a71b0542f2f7819ba0e33a88908e01b6fc49e4ce -commit 0d96b1506b2f4757fefa5d1f884d49e96a6fd4c3 -Author: Damien Miller -Date: Tue Jan 16 14:40:18 2024 +1100 +commit 96b64056c812620014b65371a9e3ac86bfcd08d5 +Author: Thorsten Kukuk +Date: Tue Nov 19 10:53:28 2024 +0100 - skip tests that use multiplexing on Windows - - Some tests here use multiplexing, skip these if DISABLE_FD_PASSING - is set. Should unbreak tests on Windows. + Add wtmpdb support as Y2038 safe wtmp replacement -commit 50080fa42f5f744b798ee29400c0710f1b59f50e +commit 1d9563a56f2ad5b0c0aeef20e19c1a03ad54f88a Author: djm@openbsd.org -Date: Thu Jan 11 04:50:28 2024 +0000 +Date: Mon Dec 2 14:06:42 2024 +0000 - upstream: don't disable RSA test when DSA is disabled; bug introduced + upstream: unbreak - in last commit - - OpenBSD-Regress-ID: 8780a7250bf742b33010e9336359a1c516f2d7b5 + OpenBSD-Commit-ID: 05b6c31f4a6e385338f43cc0e08776cea75802a1 -commit 415c94ce17288e0cdcb9e58cc91fba78d33c8457 +commit d75837b9f6d0d6cc18ed5078789ea0f3dad08f00 Author: djm@openbsd.org -Date: Thu Jan 11 01:45:58 2024 +0000 +Date: Mon Dec 2 13:37:18 2024 +0000 - upstream: make DSA testing optional, defaulting to on - - ok markus + upstream: prefer AES-GCM to AES-CTR; ok deraadt markus - OpenBSD-Regress-ID: dfc27b5574e3f19dc4043395594cea5f90b8572a + OpenBSD-Commit-ID: 8366a72e0f300ee31c5dab2c95025387ec15bbc9 -commit f9311e8921d92c5efca767227a497ab63280ac39 -Author: djm@openbsd.org -Date: Thu Jan 11 01:51:16 2024 +0000 +commit e19cd494b567a73dc390e09b47c1e21545e6116b +Author: Shiva Kaul +Date: Mon Dec 2 02:04:20 2024 -0500 - upstream: ensure key_fd is filled when DSA is disabled; spotted by + Fix compilation with DEBUG_SK enabled - tb@ + In `ssh_ecdsa_sk_verify`, the `datalen` variable was renamed to `dlen` -- but not in this debugging block. + +commit 67ace92be0718df7e0f52c0a76684fc2ebae4089 +Author: dtucker@openbsd.org +Date: Fri Nov 29 00:13:36 2024 +0000 + + upstream: Import regenerated moduli. - OpenBSD-Commit-ID: 9dd417b6eec3cf67e870f147464a8d93f076dce7 + OpenBSD-Commit-ID: 311d271bf0fab8a119e84f4f696d8cd40731692f -commit 4e838120a759d187b036036610402cbda33f3203 -Author: djm@openbsd.org -Date: Thu Jan 11 01:45:36 2024 +0000 +commit ca0697a90e5720ba4d76cb0ae9d5572b5260a16c +Author: Jeremy Stott +Date: Sat Oct 19 12:10:52 2024 +1300 - upstream: make DSA key support compile-time optional, defaulting to + Add make target for standalone sk-libfido2 - on + Add a Makefile target for sk-libfido2, the standalone fido2 security + key shared library, suitable for use with the SecurityKeyProvider + option. - ok markus@ + Add a new configure option `--with-security-key-standalone` that + optionally sets the shared library target sk-libfido2$(SHLIBEXT), and + adds it to $(TARGETS). - OpenBSD-Commit-ID: 4f8e98fc1fd6de399d0921d5b31b3127a03f581d + misc.h is required when SK_STANDALONE is defined, because of the use + of `monotime_tv` in `sk_select_by_touch`. + + Sets the shared library extension for sk-libfido2 is by setting + `SHLIBEXT` depending on the platform in configure.ac. + + Add the shared library to the CI builds in the `sk` target config to + make sure it can compile under the same conditions as + `--with-security-key-builtin`. + + Add a libssh-pic.a static library that compiles with `-fPIC` reusing + .c.lo method in sk-dummy.so for use in the shared library sk-libfido2. + + Note, a separate static library libssh-pic.a is needed, since defining + -DSK_STANDALONE excludes some symbols needed in sshkey.lo. -commit afcc9028bfc411bc26d20bba803b83f90cb84e26 -Author: jmc@openbsd.org -Date: Wed Jan 10 06:33:13 2024 +0000 +commit 74d70841efbf41b9fcc8e6f6f4777d2e9d7e2004 +Author: Arnout Engelen +Date: Fri Oct 18 13:42:38 2024 +0200 - upstream: fix incorrect capitalisation; + mdoc2man: balance nested square brackets + + I noticed the square brackets in `destination [command [argument...]` + in the synopsis for the `ssh.1` manpage were not balanced, + this balances them. - OpenBSD-Commit-ID: cb07eb06e15fa2334660ac73e98f29b6a1931984 + Signed-off-by: Arnout Engelen -commit 9707c8170c0c1baeb1e06e5a53f604498193885f +commit 8eabd2ae2ca1d7756417a1ee5b41f09c5d997634 Author: djm@openbsd.org -Date: Tue Jan 9 22:19:36 2024 +0000 +Date: Wed Nov 27 16:07:08 2024 +0000 - upstream: extend ChannelTimeout regression test to exercise multiplexed + upstream: fix argument of "Compression" directive in ssh -G config - connections and the new "global" timeout type. ok dtucker@ + dump, which used to work but broke in 9.8 - OpenBSD-Regress-ID: f10d19f697024e9941acad7c2057f73d6eacb8a2 + OpenBSD-Commit-ID: c79936242d29c70d01941b28d2d07fd0b85fe46f -commit b31b12d28de96e1d43581d32f34da8db27e11c03 +commit 53c03961769d8879a81398074ea3cb36253d4f2e Author: djm@openbsd.org -Date: Tue Jan 9 22:19:00 2024 +0000 +Date: Wed Nov 27 13:27:34 2024 +0000 - upstream: add a "global" ChannelTimeout type to ssh(1) and sshd(8) - - that watches all open channels and will close all open channels if there is - no traffic on any of them for the specified interval. This is in addition to - the existing per-channel timeouts added a few releases ago. - - This supports use-cases like having a session + x11 forwarding channel - open where one may be idle for an extended period but the other is - actively used. The global timeout would allow closing both channels when - both have been idle for too long. + upstream: new name/link for agent I-D - ok dtucker@ - - OpenBSD-Commit-ID: 0054157d24d2eaa5dc1a9a9859afefc13d1d7eb3 + OpenBSD-Commit-ID: e3420f3925a297a1b2ab7dfe7c7d274cfc8e1193 -commit 602f4beeeda5bb0eca181f8753d923a2997d0a51 +commit 785e3c9110df8f2d30e42ce8b45969c49700f35b Author: djm@openbsd.org -Date: Tue Jan 9 21:39:14 2024 +0000 +Date: Wed Nov 27 13:00:23 2024 +0000 - upstream: adapt ssh_api.c code for kex-strict + upstream: mention that biometrics may be used for FIDO key user - from markus@ ok me + verification as well as PIN. Prompted by Zack Newman, ok jmc@ - OpenBSD-Commit-ID: 4d9f256852af2a5b882b12cae9447f8f00f933ac - -commit 42ba34aba8708cf96583ff52975d95a8b47d990d -Author: Damien Miller -Date: Mon Jan 8 16:26:37 2024 +1100 + OpenBSD-Commit-ID: b774a4438c9be70012661ee278450790d21277b8 - nite that recent OSX tun/tap is unsupported - -commit 690bc125f9a3b20e47745fa8f5b5e1fd5820247f -Author: Sevan Janiyan -Date: Wed Dec 27 04:57:49 2023 +0000 - - README.platform: update tuntap url - -commit 6b8be2ccd7dd091808f86af52066b0c2ec30483a -Author: Rose <83477269+AtariDreams@users.noreply.github.com> -Date: Tue Dec 19 11:48:20 2023 -0500 +commit fd2e64c9ec9ea3e89e396be0db41aaf982ae1210 +Author: djm@openbsd.org +Date: Tue Nov 26 22:05:51 2024 +0000 - Fix compilation error in ssh-pcks11-client.c + upstream: g/c outdated XXX comments - Compilation fails becaus of an undefined reference to helper_by_ec, - because we forgot the preprocessor conditional that excludes that function - from being called in unsupported configurations. + OpenBSD-Commit-ID: 74d0c0b74994d9a4343c4d7ea4948cb34f609a6c -commit 219c8134157744886ee6ac5b8c1650abcd981f4c +commit 0ad34a6193357d286042322ea7347262a6fb0778 Author: djm@openbsd.org -Date: Mon Jan 8 05:11:18 2024 +0000 +Date: Tue Nov 26 22:02:28 2024 +0000 - upstream: Remove outdated note from PROTOCOL.mux + upstream: regression test for UpdateHostkeys with multiple keys backed - Port forward close by control master is already implemented - by `mux_master_process_close_fwd` in `mux.c` + by ssh-agent. Patch from Maxime Rey. - GHPR442 from bigb4ng - - OpenBSD-Commit-ID: ad0734fe5916d2dc7dd02b588906cea4df0482fb + OpenBSD-Regress-ID: 1777ab6e639e57c0e20cbcb6df60455b49fd8bb3 -commit 4c3cf362631ccc4ffd422e572f075d5d594feace +commit 84023656d91b78f1ef86c8321ec563f2e90f7227 Author: djm@openbsd.org -Date: Mon Jan 8 05:05:15 2024 +0000 +Date: Tue Nov 26 22:01:37 2024 +0000 - upstream: fix missing field in users-groups-by-id@openssh.com reply + upstream: Explicitly specify the signature algorithm when signing + + hostkeys-prove requests. - documentation + Fixes a corner-case triggered by UpdateHostKeys with one or more unknown + host keys stored in ssh-agent where sshd refuses to accept the signature + coming back from the agent. - GHPR441 from TJ Saunders + Report/fix from Maxime Rey - OpenBSD-Commit-ID: ff5733ff6ef4cd24e0758ebeed557aa91184c674 + OpenBSD-Commit-ID: 460c7d527a24f92b7e5f68ca1a2fa242ebf0d086 -commit f64cede2a3c298b50a2659a8b53eb3ab2c0b8d23 +commit d1c1cfc5e4e9b43593d4642810ea8135e4c7db49 Author: djm@openbsd.org -Date: Mon Jan 8 04:10:03 2024 +0000 +Date: Tue Nov 26 21:23:35 2024 +0000 - upstream: make kex-strict section more explicit about its intent: + upstream: when using RSA keys to sign messages, select the - banning all messages not strictly required in KEX + signature algorithm based on the requested hash algorithm ("-Ohashalg=xxx"). - OpenBSD-Commit-ID: fc33a2d7f3b7013a7fb7500bdbaa8254ebc88116 - -commit 698fe6fd61cbcb8e3e0e874a561d4335a49fbde5 -Author: Damien Miller -Date: Mon Jan 8 14:46:19 2024 +1100 - - update fuzzer example makefile to clang16 - -commit fc332cb2d602c60983a8ec9f89412754ace06425 -Author: Damien Miller -Date: Mon Jan 8 14:45:49 2024 +1100 - - unbreak fuzzers - missing pkcs11_make_cert() + This allows using something other than rsa-sha2-512, which may not + be supported on all signing backends, e.g. some smartcards only + support SHA256. - provide stub for use in fuzzer harness - -commit 9ea0a4524ae3276546248a926b6641b2fbc8421b -Author: Damien Miller -Date: Mon Jan 8 14:45:14 2024 +1100 - - unbreak fuzzers for clang16 + Patch from Morten Linderud; ok markus@ - getopt() needs a throw() attribute to compile, so supply one when compiling - things with C++ + OpenBSD-Commit-ID: 246353fac24e92629263996558c6788348363ad7 -commit a72833d00788ef91100c643536ac08ada46440e1 +commit ac7544654441280071b90a4129a47467d40f2389 Author: djm@openbsd.org -Date: Mon Jan 8 00:34:33 2024 +0000 +Date: Sun Nov 24 23:47:50 2024 +0000 - upstream: remove ext-info-* in the kex.c code, not in callers; + upstream: turn off CDIAGFLAGS and turn back on INSTALL_STRIP - with/ok markus@ + accidentally changed in last commit - OpenBSD-Commit-ID: c06fe2d3a0605c517ff7d65e38ec7b2d1b0b2799 + OpenBSD-Commit-ID: 6d07e4606997e36b860621a14dd41975f2902f8f -commit 86f9e96d9bcfd1f5cd4bf8fb57a9b4c242df67df -Author: djm@openbsd.org -Date: Mon Jan 8 00:30:39 2024 +0000 +commit 953fa5b59afb04c3c74ed82d7bace65c13cd8baa +Author: Darren Tucker +Date: Sat Nov 9 11:41:44 2024 +1100 - upstream: fix typo; spotted by Albert Chin + Disable security key for bigendian interop. - OpenBSD-Commit-ID: 77140b520a43375b886e535eb8bd842a268f9368 + It doesn't currently work. It's not clear why, but I suspect + sk-dummy.so ends up being built for the wrong architecture. -commit f0cbd26ec91bd49719fb3eea7ca44d2380318b9a -Author: dtucker@openbsd.org -Date: Thu Jan 4 09:51:49 2024 +0000 +commit a80eb71c428c474098087c672398f200be8fabdf +Author: Darren Tucker +Date: Sat Nov 9 05:14:16 2024 +1100 - upstream: Import regenerated moduli. + Reshuffle OpenWRT test configs. - OpenBSD-Commit-ID: 5a636f6ca7f25bfe775df4952f7aac90a7fcbbee + Move the the flags used by the OpenWRT distro to mipsel target and + enable OpenSSL on all targets to improve coverage. + + Explicitly disable security key and openssl on mips target so that host + end of the bigendian interop tests don't attempt them and fail (since + they're not enabled on the target side). -commit 64ddf776531ca4933832beecc8b7ebe1b937e081 -Author: jsg@openbsd.org -Date: Wed Dec 20 00:06:25 2023 +0000 +commit d2709c461359e4129311cdff81ee05242d6c53cd +Author: Darren Tucker +Date: Sat Nov 9 03:26:08 2024 +1100 - upstream: spelling; ok markus@ - - OpenBSD-Commit-ID: 9d01f2e9d59a999d5d42fc3b3efcf8dfb892e31b + Add keytype to bigendian interop test. -commit 503fbe9ea238a4637e8778208bde8c09bcf78475 -Author: jmc@openbsd.org -Date: Tue Dec 19 06:57:34 2023 +0000 +commit 50ac0f0e0627d29fd9becf5e15e8ceca5ad18078 +Author: Darren Tucker +Date: Sat Nov 9 03:24:29 2024 +1100 + + Ignore chown failure, eg due to dangling symlinks. + +commit 9e528e65a03245cf28e814f09b88c701bec935d1 +Author: Darren Tucker +Date: Sat Nov 2 18:05:41 2024 +1100 - upstream: sort -C, and add to usage(); ok djm + Test bigendian interop. - OpenBSD-Commit-ID: 80141b2a5d60c8593e3c65ca3c53c431262c812f + Where our test target is a bigendian system, do an additional build on + the runner host (which is little endian) and test interop between the two. + Should hopefully catch obvious endianness bugs. -commit 5413b1c7ff5a19c6a7d44bd98c5a83eb47819ba6 -Author: djm@openbsd.org -Date: Tue Dec 19 06:41:14 2023 +0000 +commit dd416f5bfa96ac1ff44b27a93f7b55ee627c6baf +Author: Darren Tucker +Date: Fri Nov 1 19:44:29 2024 +1100 - upstream: correct section numbers; from Ed Maste + Allow overridding TEST_SSH_SSHD. - OpenBSD-Commit-ID: e289576ee5651528404cb2fb68945556052cf83f + This will allow tests to specify an alternative sshd, eg on a remote + machine with different endianness. -commit 430ef864645cff83a4022f5b050174c840e275da +commit 82662d562cf54829df8a941cdfb2fd307e1d9a90 Author: djm@openbsd.org -Date: Mon Dec 18 15:58:56 2023 +0000 +Date: Wed Nov 6 22:51:26 2024 +0000 - upstream: match flag type (s/int/u_int) + upstream: ssh-agent implemented an all-or-nothing allow-list of + + FIDO application IDs for security key-backed keys, to prevent web key handles + from being used remotely as this would likely lead to unpleasant surprises. + By default, only application IDs that start with "ssh:*" are allowed. - OpenBSD-Commit-ID: 9422289747c35ccb7b31d0e1888ccd5e74ad566a + This adds a -Owebsafe-allow=... argument that can override the default + list with a more or less restrictive one. The default remains unchanged. + + ok markus@ + + OpenBSD-Commit-ID: 957c1ed92a8d7c87453b9341f70cb3f4e6b23e8d -commit 1036d77b34a5fa15e56f516b81b9928006848cbd -Author: Damien Miller -Date: Fri Dec 22 17:56:26 2023 +1100 +commit 593a0b65c55c1e06a8c22b084aefc395aedb0127 +Author: jca@openbsd.org +Date: Mon Nov 4 21:59:15 2024 +0000 - better detection of broken -fzero-call-used-regs + upstream: Ignore extra groups that don't fit in the buffer passed - gcc 13.2.0 on ppc64le refuses to compile some function, including - cipher.c:compression_alg_list() with an error: + to getgrouplist(3) - > sorry, unimplemented: argument ‘used’ is not supportedcw - > for ‘-fzero-call-used-regs’ on this target + Our kernel supports 16 groups (NGROUPS_MAX), but nothing prevents + an admin from adding a user to more groups. With that tweak we'll keep + on ignoring them instead of potentially reading past the buffer passed to + getgrouplist(3). That behavior is explicitely described in initgroups(3). - This extends the autoconf will-it-work test with a similarly- - structured function that seems to catch this. + ok millert@ gilles@ - Spotted/tested by Colin Watson; bz3645 + OpenBSD-Commit-ID: a959fc45ea3431b36f52eda04faefc58bcde00db -commit 8241b9c0529228b4b86d88b1a6076fb9f97e4a99 +commit e7adebeff3a9d038d0eaeeb0fcefedf29acb7e90 Author: Damien Miller -Date: Tue Dec 19 01:59:50 2023 +1100 +Date: Mon Nov 4 14:39:27 2024 +1100 - crank versions + Add git signing key for Tim Rice -commit 2f2c65cb5f1518a9c556d3e8efa27ea0ca305c6b -Author: Damien Miller -Date: Tue Dec 19 01:59:06 2023 +1100 +commit da4b84845e874f12af7e0686170fa391c919d1df +Author: Darren Tucker +Date: Fri Nov 1 18:51:22 2024 +1100 - depend + Correct path to c-cpp.yml file in workflow config. -commit e48cdee8e19059203b1aeeabec2350b8375fa61f -Author: djm@openbsd.org -Date: Mon Dec 18 14:50:08 2023 +0000 +commit 28740aa2c75392a9c4191eb9523f9b20853e2932 +Author: Darren Tucker +Date: Fri Nov 1 18:44:42 2024 +1100 - upstream: regress test for agent PKCS#11-backed certificates - - OpenBSD-Regress-ID: 38f681777cb944a8cc3bf9d0ad62959a16764df9 + Test new OpenSSL and LibreSSL releases.` -commit 2f512f862df1d5f456f82a0334c9e8cc7208a2a1 -Author: djm@openbsd.org -Date: Mon Dec 18 14:49:39 2023 +0000 +commit a74809fe06540f16231b354ffe21fcbf39e81f73 +Author: Darren Tucker +Date: Fri Nov 1 18:44:00 2024 +1100 - upstream: regress test for constrained PKCS#11 keys - - OpenBSD-Regress-ID: b2f26ae95d609d12257b43aef7cd7714c82618ff + Add nbsd10 default test config. -commit cdddd66412ca5920ed4d3ebbfa6ace12dbd9b82f -Author: djm@openbsd.org -Date: Mon Dec 18 14:48:44 2023 +0000 +commit 88b35cbdc1500efece65cd6a9a20a72cf7e46eaa +Author: Damien Miller +Date: Wed Oct 30 14:25:14 2024 +1100 - upstream: openssh-9.6 - - OpenBSD-Commit-ID: 21759837cf0e0092d9a2079f8fb562071c11016b + fix uint64_t types; reported by Tom G. Christensen + +commit ef7c26cd2f0f9a8222f851d1e551f6dfd3113f8b +Author: Damien Miller +Date: Sun Oct 27 13:28:11 2024 +1100 + + htole64() etc for systems without endian.h -commit 6d51feab157cedf1e7ef5b3f8781ca8ff9c4ab1b +commit 0c3927c45f8a57b511c874c4d51a8c89414f74ef Author: djm@openbsd.org -Date: Mon Dec 18 14:48:08 2023 +0000 +Date: Sun Oct 27 02:06:59 2024 +0000 - upstream: ssh-agent: record failed session-bind attempts - - Record failed attempts to session-bind a connection and refuse signing - operations on that connection henceforth. - - Prevents a future situation where we add a new hostkey type that is not - recognised by an older ssh-agent, that consequently causes session-bind - to fail (this situation is only likely to arise when people mix ssh(1) - and ssh-agent(1) of different versions on the same host). Previously, - after such a failure the agent socket would be considered unbound and - not subject to restriction. - - Spotted by Jann Horn + upstream: explicitly include endian.h - OpenBSD-Commit-ID: b0fdd023e920aa4831413f640de4c5307b53552e + OpenBSD-Commit-ID: 13511fdef7535bdbc35b644c90090013da43a318 -commit 7ef3787c84b6b524501211b11a26c742f829af1a +commit cf3e48ee8ba1beeccddd2f203b558fa102be67a2 Author: djm@openbsd.org -Date: Mon Dec 18 14:47:44 2023 +0000 +Date: Sun Oct 27 02:06:01 2024 +0000 - upstream: ban user/hostnames with most shell metacharacters + upstream: fix ML-KEM768x25519 KEX on big-endian systems; spotted by - This makes ssh(1) refuse user or host names provided on the - commandline that contain most shell metacharacters. + jsg@ feedback/ok deraadt@ - Some programs that invoke ssh(1) using untrusted data do not filter - metacharacters in arguments they supply. This could create - interactions with user-specified ProxyCommand and other directives - that allow shell injection attacks to occur. + OpenBSD-Commit-ID: 26d81a430811672bc762687166986cad40d28cc0 + +commit ae566d51b64fa3dce7063e7745b9b35f8f47abde +Author: naddy@openbsd.org +Date: Fri Oct 25 21:53:24 2024 +0000 + + upstream: mlkem768x25519-sha256 has been promoted to default key - It's a mistake to invoke ssh(1) with arbitrary untrusted arguments, - but getting this stuff right can be tricky, so this should prevent - most obvious ways of creating risky situations. It however is not - and cannot be perfect: ssh(1) has no practical way of interpreting - what shell quoting rules are in use and how they interact with the - user's specified ProxyCommand. + exchange - To allow configurations that use strange user or hostnames to - continue to work, this strictness is applied only to names coming - from the commandline. Names specified using User or Hostname - directives in ssh_config(5) are not affected. + OpenBSD-Commit-ID: 5a3259a193fd42108a869ebf650b95b5f2d08dcf + +commit 3af1dba1384ca896df6e973c70398c41d36de1ea +Author: Darren Tucker +Date: Fri Oct 25 19:04:30 2024 +1100 + + Retire the minix3 test config. - feedback/ok millert@ markus@ dtucker@ deraadt@ + It got broken by the sshd-auth change, it's not obvious why, and the + platform lacks the debugging tools (eg gdb, strace) to figure it out. + The upstream project seems effectively dead (6 years since the last + commit, 10 since the last release). It was useful while it lasted + (we found a real bug because of it) but its time seems to have passed. + +commit 3b240cc44b8de9175280ddbe59331317d427b0e3 +Author: Preetish Amballi +Date: Mon Oct 21 14:07:02 2024 +0000 + + Updated gitignore to ignore sshd-session and sshd-auth targets + +commit 326495744f06a0ab18ee0d16f87b3fe91cac92fb +Author: Darren Tucker +Date: Fri Oct 25 19:01:02 2024 +1100 + + Simplify pselect shim and remove side effects. - OpenBSD-Commit-ID: 3b487348b5964f3e77b6b4d3da4c3b439e94b2d9 + Instead of maintaing state (pipe descriptors, signal handlers) across + pselect-on-select invocations, set up and restore them each call. + This prevents outside factors (eg a closefrom or signal handler + installation) from potentially causing problems. This does result in a + drop in throughput of a couple of percent on geriatric platforms without + a native pselect due to the extra overhead. Tweaks & ok djm@ -commit 0cb50eefdd29f0fec31d0e71cc4b004a5f704e67 +commit e53b615f3934ffac1efb3c1e491d126b9b09fd24 Author: djm@openbsd.org -Date: Mon Dec 18 14:47:20 2023 +0000 +Date: Fri Oct 25 01:34:18 2024 +0000 - upstream: stricter handling of channel window limits - - This makes ssh/sshd more strict in handling non-compliant peers that - send more data than the advertised channel window allows. Previously - the additional data would be silently discarded. This change will - cause ssh/sshd to terminate the connection if the channel window is - exceeded by more than a small grace allowance. + upstream: promote mlkem768x25519-sha256 to be the default key exchange; ok markus@ - OpenBSD-Commit-ID: 811e21b41831eba3dd7f67b3d409a438f20d3037 + OpenBSD-Commit-ID: fc673065e6505bb06b2e2b9362f78ccb4200a828 -commit 4448a2938abc76e6bd33ba09b2ec17a216dfb491 +commit de644b1831b970f6655f871c051774cc871e8e74 Author: djm@openbsd.org -Date: Mon Dec 18 14:46:56 2023 +0000 +Date: Thu Oct 24 03:28:34 2024 +0000 - upstream: Make it possible to load certs from PKCS#11 tokens - - Adds a protocol extension to allow grafting certificates supplied by - ssh-add to keys loaded from PKCS#11 tokens in the agent. + upstream: test SIGUSR1 dropping all keys from ssh-agent - feedback/ok markus@ - - OpenBSD-Commit-ID: bb5433cd28ede2bc910996eb3c0b53e20f86037f + OpenBSD-Regress-ID: 8654b9aa8eb695b1499fffc408c25319592bf0e0 -commit 881d9c6af9da4257c69c327c4e2f1508b2fa754b +commit e86d7a077ce9a2b9ee9d4138c358a17cbdb786f9 Author: djm@openbsd.org -Date: Mon Dec 18 14:46:12 2023 +0000 +Date: Thu Oct 24 03:15:47 2024 +0000 - upstream: apply destination constraints to all p11 keys + upstream: amake ssh-agent drop all keys when it receives SIGUSR1; - Previously applied only to the first key returned from each token. + let's users zap keys without access to $SSH_AUTH_SOCK - ok markus@ + ok deraadt@ - OpenBSD-Commit-ID: 36df3afb8eb94eec6b2541f063d0d164ef8b488d + OpenBSD-Commit-ID: dae9db0516b1011e5ba8c655ac702fce42e6c023 -commit a7ed931caeb68947d30af8a795f4108b6efad761 +commit 94cdfebec852a2429c008cc2a55f8e4183f36972 Author: djm@openbsd.org -Date: Mon Dec 18 14:45:49 2023 +0000 +Date: Thu Oct 24 03:14:37 2024 +0000 - upstream: add "ext-info-in-auth@openssh.com" extension - - This adds another transport protocol extension to allow a sshd to send - SSH2_MSG_EXT_INFO during user authentication, after the server has - learned the username that is being logged in to. + upstream: relax valid_domain() checks to allow an underscore as the - This lets sshd to update the acceptable signature algoritms for public - key authentication, and allows these to be varied via sshd_config(5) - "Match" directives, which are evaluated after the server learns the - username being authenticated. + first character. ok deraadt@ - Full details in the PROTOCOL file - - OpenBSD-Commit-ID: 1de7da7f2b6c32a46043d75fcd49b0cbb7db7779 + OpenBSD-Commit-ID: 3f8be6d32496e5596dd8b14e19cb067ddd7969ef -commit 1edb00c58f8a6875fad6a497aa2bacf37f9e6cd5 -Author: djm@openbsd.org -Date: Mon Dec 18 14:45:17 2023 +0000 +commit 1b05d5437bf45bee5e3104772dea06ed51764f1b +Author: dtucker@openbsd.org +Date: Tue Oct 22 07:13:28 2024 +0000 - upstream: implement "strict key exchange" in ssh and sshd + upstream: Remove sshd logfile in start_sshd - This adds a protocol extension to improve the integrity of the SSH - transport protocol, particular in and around the initial key exchange - (KEX) phase. + ... and ssh and sshd log wrappers before recreating them. Prevents "can't + create" errors during tests when running tests without SUDO after having + run them with SUDO. - Full details of the extension are in the PROTOCOL file. + OpenBSD-Regress-ID: 2f0a83532e3dccd673a9bf0291090277268c69a6 + +commit 307ab3c7720f8879b835614b02687358ee4df9b9 +Author: dtucker@openbsd.org +Date: Tue Oct 22 06:16:26 2024 +0000 + + upstream: Add a sshd debug wrapper - with markus@ + ... to run all of the subprograms from the build directory while + developing and debugging. Should help prevent accidentally testing + against unchanged installed sshd-auth and sshd-session binaries. ok djm@ - OpenBSD-Commit-ID: 2a66ac962f0a630d7945fee54004ed9e9c439f14 + OpenBSD-Commit-ID: 61760cdc98c2bc8f1e9f83a6f97cca0f66b52e69 -commit 59d691b886c79e70b1d1c4ab744e81fd176222fd -Author: Damien Miller -Date: Mon Dec 18 14:49:11 2023 +1100 +commit 87bd1cb3ccba5e91d2650eb7f753c898ee43858e +Author: dtucker@openbsd.org +Date: Tue Oct 22 06:13:00 2024 +0000 - better detection of broken -fzero-call-used-regs + upstream: Make debug call printf("%s", NULL) safe. - Use OSSH_CHECK_CFLAG_LINK() for detection of these flags and extend - test program to exercise varargs, which seems to catch more stuff. + Prevents problems on platforms where this isn't safe (which it's not + required to be). ok djm@ - ok dtucker@ + OpenBSD-Commit-ID: 8fa4ce3ad90915c925b81b99a79ab920b0523387 + +commit c44c349edd157b2c00c42bd5ef5f9dfb37de26f3 +Author: Darren Tucker +Date: Tue Oct 22 17:48:32 2024 +1100 + + Resync cvsid missed in commit 6072e4c9. -commit aa7b21708511a6d4aed3839fc9f6e82e849dd4a1 +commit fe4305c37ffe53540a67586854e25f05cf615849 Author: djm@openbsd.org -Date: Wed Dec 13 03:28:19 2023 +0000 +Date: Fri Oct 18 05:53:26 2024 +0000 - upstream: when invoking KnownHostsCommand to determine the order of - - host key algorithms to request, ensure that the hostname passed to the - command is decorated with the port number for ports other than 22. - - This matches the behaviour of KnownHostsCommand when invoked to look - up the actual host key. + upstream: mention that LocalForward and RemoteForward can accept Unix - bz3643, ok dtucker@ + domain socket paths; GHPR115 - OpenBSD-Commit-ID: 5cfabc0b7c6c7ab473666df314f377b1f15420b1 + OpenBSD-Commit-ID: a8a34d0a0c51a9ddab3dfce615f9878fa76ef842 -commit 4086bd6652c0badccc020218a62190a7798fb72c -Author: markus@openbsd.org -Date: Fri Dec 8 09:18:39 2023 +0000 +commit 9c97b6af8e052ab5ffe0f9096fadc8f9a4d0ed0f +Author: djm@openbsd.org +Date: Fri Oct 18 05:45:40 2024 +0000 - upstream: prevent leak in sshsig_match_principals; ok djm@ + upstream: remove duplicate check; GHPR392 from Pedro Martelletto - OpenBSD-Commit-ID: 594f61ad4819ff5c72dfe99ba666a17f0e1030ae + OpenBSD-Commit-ID: 597ab7dd3f0e78939d2659fc1904d0f39ee95487 -commit 19d3ee2f3adf7d9a606ff015c1e153744702c4c9 +commit d9cd208e89a471a3ff8adfcec68d6210af9e9fd5 Author: djm@openbsd.org -Date: Wed Dec 6 21:06:48 2023 +0000 +Date: Fri Oct 18 05:37:24 2024 +0000 - upstream: short circuit debug log processing early if we're not going + upstream: allow "-" as output file for moduli screening - to log anything. From Kobe Housen + based on GHPR393 - OpenBSD-Commit-ID: 2bcddd695872a1bef137cfff7823044dcded90ea - -commit 947affad4831df015c498c00c6351ea6f13895d5 -Author: Darren Tucker -Date: Mon Nov 27 09:37:28 2023 +1100 - - Add tests for OpenSSL 3.2.0 and 3.2 stable branch. + OpenBSD-Commit-ID: 1517763764eb55d03a6092dd120d2909c6fef0e1 -commit 747dce36206675ca6b885010a835733df469351b -Author: Darren Tucker -Date: Sat Nov 25 09:03:38 2023 +1100 +commit 5eb5c4b2820d0636b1eccee646fb32ec946c4a95 +Author: djm@openbsd.org +Date: Fri Oct 18 05:32:51 2024 +0000 - Use non-zero arg in compiler test program. + upstream: ssh-keyscan doesn't need it's own sshfatal() definition, it + + can use the shared one from fatal.c + + based on GHPR401 from lengyijun - Now that we're running the test program, passing zero to the test function - can cause divide-by-zero exceptions which might show up in logs. + OpenBSD-Commit-ID: 8ea75ea99f27f464c9223cbc89cb046ccf9cd5c4 -commit 3d44a5c56585d1c351dbc006240a591b6da502b1 -Author: dtucker@openbsd.org -Date: Fri Nov 24 00:31:30 2023 +0000 +commit 0a1e75499e2c6fc258ee903645c878480949f362 +Author: djm@openbsd.org +Date: Fri Oct 18 05:14:51 2024 +0000 - upstream: Plug mem leak of msg when processing a quit message. + upstream: in _ssh_order_hostkeyalgs() consider ECDSA curve type when - Coverity CID#427852, ok djm@ + arranging the hostkey algorithms. AFAIK this code is unused in OpenSSH, but I + guess others are using it - OpenBSD-Commit-ID: bf85362addbe2134c3d8c4b80f16601fbff823b7 + based on GHPR387 from Pawel Jakub Dawidek + + OpenBSD-Commit-ID: 4d462495ac0c40f7b7dd66178e0005b9b2128225 -commit 1d7f9b6e297877bd00973e6dc5c0642dbefc3b5f -Author: dtucker@openbsd.org -Date: Thu Nov 23 03:37:05 2023 +0000 +commit d01ee7a88c5f4b1aa8c75a7c739f8f3bc1ad8bde +Author: djm@openbsd.org +Date: Fri Oct 18 05:03:34 2024 +0000 - upstream: Include existing mux path in debug message. + upstream: require control-escape character sequences passed via the '-e + + ^x' commandline to be exactly two characters long. Avoids one by OOB read if + ssh is invoked as "ssh -e^ ..." - OpenBSD-Commit-ID: 1c3641be10c2f4fbad2a1b088a441d072e18bf16 + Spotted by Maciej Domanski in GHPR368 + + OpenBSD-Commit-ID: baa72bc60898fc5639e6c62de7493a202c95823d -commit f29934066bd0e561a2e516b7e584fb92d2eedee0 -Author: Darren Tucker -Date: Thu Nov 23 19:41:27 2023 +1100 +commit 74ff6382f5743e09930e6cbd195dac65cd6062c9 +Author: djm@openbsd.org +Date: Fri Oct 18 04:30:09 2024 +0000 - Add an Ubuntu 22.04 test VM. + upstream: remove addr.[ch] functions that are unused and + + visbility-restrict ones that are unused outside the implementation itself; + based on GHPR#282 by tobias@ - This is the same version as Github's runners so most of the testing on - it is over there, but having a local VM makes debugging much easier. + OpenBSD-Commit-ID: a0140f2418b4d46cfaa7b33febc0a0931f9b2744 -commit a93284a780cd3972afe5f89086b75d564ba157f3 -Author: Darren Tucker -Date: Thu Nov 23 19:36:22 2023 +1100 +commit a9d6d7d93c533fa729f08b405e786d912553f33e +Author: djm@openbsd.org +Date: Fri Oct 18 04:14:59 2024 +0000 - Add gcc-12 -Werror test on Ubuntu 22.04. + upstream: unreachable POLLERR case; from ya0guang via GHPR485 - Explictly specify gcc-11 on Ubuntu 22.04 (it's the system compiler). + OpenBSD-Commit-ID: b3c82655190532b01eb817e532742cfaa4687eff -commit 670f5a647e98b6fd95ad64f789f87ee3274b481b -Author: Darren Tucker -Date: Thu Nov 23 19:34:57 2023 +1100 +commit d76424bf279ff951383e21213eb3759ea4090674 +Author: djm@openbsd.org +Date: Fri Oct 18 04:11:54 2024 +0000 - Check return value from write to prevent warning. + upstream: s/Sx/Cm/ for external references; from Domen Puncer - ... and since we're testing for flags with -Werror, this caused - configure to mis-detect compiler flags. + Kugler via GHPR501 + + OpenBSD-Commit-ID: f864a34feb5d5ff17160cf7c42ad0f7744fe8a3f -commit cea007d691cfedfa07a5b8599f97ce0511f53fc9 -Author: Darren Tucker -Date: Wed Nov 22 21:18:55 2023 +1100 +commit ca204b994e2981e7bf95627b3105408917105649 +Author: naddy@openbsd.org +Date: Mon Oct 14 23:53:34 2024 +0000 - Run compiler test program when compiling natively. + upstream: mention SshdAuthPath option; ok djm@ - ok djm@ + OpenBSD-Commit-ID: 9a5d3add25e4e77bd3805bc5583a842ecf34d85c -commit ee0d305828f13536c0a416bbf9c3e81039d9ea55 +commit be27770e840c4dd9d9fcad1aa879400c727d7c2f Author: Darren Tucker -Date: Wed Nov 22 21:18:07 2023 +1100 +Date: Fri Oct 18 13:37:55 2024 +1100 - Factor out compiler test program into a macro. + Remove references to systrace and pledge sandboxes. ok djm@ -commit de304c76316b029df460673725a9104224b9959b -Author: Darren Tucker -Date: Wed Nov 22 08:55:36 2023 +1100 - - Add fbsd14 VM to test pool. +commit 49e64bf63fbf2f14961062dafe8ef08cb816bb08 +Author: Pavel Miadzvedzeu +Date: Wed Apr 24 10:19:56 2024 +0300 -commit 99a2df5e1994cdcb44ba2187b5f34d0e9190be91 -Author: Darren Tucker -Date: Tue Nov 21 16:19:29 2023 +1100 - - Expand -fzero-call-used-regs test to cover gcc 11. - - It turns out that gcc also has some problems with -fzero-call-used-regs, - at least v11 on mips. Previously the test in OSSH_CHECK_CFLAG_COMPILE - was sufficient to catch it with "=all", but not sufficient for "=used". - Expand the testcase and include it in the other tests for good measure. - See bz#3629. ok djm@. + Fix "undeclared 'ut'" error by replacing it with 'utx' -commit ff220d4010717f7bfbbc02a2400666fb9d24f250 +commit 67f684733f60f66479854a2867b953de731e71b2 Author: Darren Tucker -Date: Tue Nov 21 14:04:34 2023 +1100 +Date: Thu Oct 17 20:50:29 2024 +1100 - Stop using -fzero-call-used-regs=all + Seed RNG when starting up sshd-auth. - ... since it seems to be problematic with several different versions of - clang. Only use -fzero-call-used-regs=used which is less - problematic, except with Apple's clang where we don't use it at all. - bz#3629, ok djm@ + Makes builds configured --without-openssl work again since otherwise + the first use of the RNG comes after the sandbox init and it can't + open /dev/random. -commit 2a19e02f36b16f0f6cc915f7d1e60ead5e36303b +commit c06c681aeebbe8e84e7410095514e7ee91f7e6cb Author: Darren Tucker -Date: Tue Nov 21 14:02:18 2023 +1100 +Date: Thu Oct 17 19:18:23 2024 +1100 - Allow for vendor prefix on clang version numbers. - - Correctly detects the version of OpenBSD's native clang, as well as - Apple's. Spotted tb@, ok djm@. + MacOS 12 runners are deprecated, replace with 15. -commit c52db0114826d73eff6cdbf205e9c1fa4f7ca6c6 -Author: djm@openbsd.org -Date: Mon Nov 20 02:50:00 2023 +0000 +commit 39db1f23bafb48a7c0cc9c65c716a0370f4cc677 +Author: Damien Miller +Date: Thu Oct 17 13:28:47 2024 +1100 - upstream: set errno=EAFNOSUPPORT when filtering addresses that don't - - match AddressFamily; yields slightly better error message if no address - matches. bz#3526 - - OpenBSD-Commit-ID: 29cea900ddd8b04a4d1968da5c4a893be2ebd9e6 + Fix lookup path for sshd-auth; bz3745 -commit 26f3f3bbc69196d908cad6558c8c7dc5beb8d74a -Author: djm@openbsd.org -Date: Wed Nov 15 23:03:38 2023 +0000 +commit c537eeb1ae5f069450053b0027e64efe5bdb37d2 +Author: Damien Miller +Date: Wed Oct 16 08:28:21 2024 +1100 - upstream: when connecting via socket (the default case), filter - - addresses by AddressFamily if one was specified. Fixes the case where, if - CanonicalizeHostname is enabled, ssh may ignore AddressFamily. bz5326; ok - dtucker - - OpenBSD-Commit-ID: 6c7d7751f6cd055126b2b268a7b64dcafa447439 + fix breakage; missing saved_argc symbol -commit 050c335c8da43741ed0df2570ebfbd5d1dfd0a31 -Author: djm@openbsd.org -Date: Wed Nov 15 22:51:49 2023 +0000 +commit 98a0883bdef28a06c7e017f27adf21ba57898bf4 +Author: Damien Miller +Date: Mon Oct 14 17:17:50 2024 +1100 - upstream: when deciding whether to enable keystroke timing - - obfuscation, only consider enabling it when a channel with a tty is open. - - Avoids turning on the obfucation when X11 forwarding only is in use, - which slows it right down. Reported by Roger Marsh - - OpenBSD-Commit-ID: c292f738db410f729190f92de100c39ec931a4f1 + fix capsicum sandbox -commit 676377ce67807a24e08a54cd60ec832946cc6cae -Author: tobhe@openbsd.org -Date: Mon Nov 13 09:18:19 2023 +0000 +commit 164ea4380564a2a83713eacf71908e3946e5e4e4 +Author: Damien Miller +Date: Mon Oct 14 17:16:41 2024 +1100 - upstream: Make sure sftp_get_limits() only returns 0 if 'limits' - - was initialized. This fixes a potential uninitialized use of 'limits' in - sftp_init() if sftp_get_limits() returned early because of an unexpected - message type. - - ok djm@ - - OpenBSD-Commit-ID: 1c177d7c3becc1d71bc8763eecf61873a1d3884c + put back some portable bits for sshd-auth.c -commit 64e0600f23c6dec36c3875392ac95b8a9100c2d6 -Author: Darren Tucker -Date: Mon Nov 13 20:03:31 2023 +1100 +commit f8edf08c258ee2918689872c4702302052729726 +Author: Damien Miller +Date: Mon Oct 14 14:49:25 2024 +1100 - Test current releases of LibreSSL and OpenSSL. - - Retire some of the older releases. + there's only one sandbox, move to a static global -commit c8ed7cc545879ac15f6ce428be4b29c35598bb2a -Author: dtucker@openbsd.org -Date: Wed Nov 1 02:08:38 2023 +0000 +commit 4482f0042b41d3d63c3845d7ba9fcf47c9252a84 +Author: Damien Miller +Date: Mon Oct 14 14:49:20 2024 +1100 - upstream: Specify ssh binary to use - - ... instead of relying on installed one. Fixes test failures in -portable - when running tests prior to installation. - - OpenBSD-Regress-ID: b6d6ba71c23209c616efc805a60d9a445d53a685 + depend -commit e9fc2c48121cada1b4dcc5dadea5d447fe0093c3 -Author: Darren Tucker -Date: Wed Nov 1 13:11:31 2023 +1100 +commit 74856204a353a187dc6e7706c6cf84b7f14d775d +Author: djm@openbsd.org +Date: Mon Oct 14 03:02:08 2024 +0000 - Put long-running test targets on hipri runners. + upstream: regress support for split sshd-auth binary - Some of the selfhosted test targets take a long time to run for various - reasons, so label them for "libvirt-hipri" runners so that they can - start immediately. This should reduce the time to complete all tests. + OpenBSD-Regress-ID: df7d18a87b475f70004770f0f4e404adba5f6ab7 -commit 7ddf27668f0e21233f08c0ab2fe9ee3fdd6ab1e2 +commit 461741083d7254595fecea274e60fe3ebf3ce3f9 Author: djm@openbsd.org -Date: Wed Nov 1 00:29:46 2023 +0000 +Date: Fri Sep 27 01:05:54 2024 +0000 - upstream: add some tests of forced commands overriding Subsystem + upstream: test some more Match syntax, including criteria=arg and - directives + negations - OpenBSD-Regress-ID: eb48610282f6371672bdf2a8b5d2aa33cfbd322b + OpenBSD-Regress-ID: 67476baccc60bf1a255fd4e329ada950047b8b8d -commit fb06f9b5a065dfbbef5916fc4accc03c0bf026dd -Author: dtucker@openbsd.org -Date: Tue Oct 31 04:15:40 2023 +0000 +commit 6072e4c9385713e9c166f32cfca6a7e603d4f0b8 +Author: djm@openbsd.org +Date: Mon Oct 14 01:57:50 2024 +0000 - upstream: Don't try to use sudo inside sshd log wrapper. - - We still need to check if we're using sudo since we don't want to chown - unecessarily, as on some platforms this causes an error which pollutes - stderr. We also don't want to unnecessarily invoke sudo, since it's - running in the context of the proxycommand, on *other* platforms it - may not be able to authenticate, and if we're using SUDO then it should - already be privileged. + upstream: Split per-connection sshd-session binary - OpenBSD-Regress-ID: 70d58df7503db699de579a9479300e5f3735f4ee - -commit fc3cc33e88c242c704781c6c48087838f1dcfa2a -Author: dtucker@openbsd.org -Date: Tue Oct 31 02:58:45 2023 +0000 - - upstream: Only try to chmod logfile if we have sudo. If we don't have + This splits the user authentication code from the sshd-session + binary into a separate sshd-auth binary. This will be executed by + sshd-session to complete the user authentication phase of the + protocol only. - sudo then we won't need to chmod. + Splitting this code into a separate binary ensures that the crucial + pre-authentication attack surface has an entirely disjoint address + space from the code used for the rest of the connection. It also + yields a small runtime memory saving as the authentication code will + be unloaded after thhe authentication phase completes. - OpenBSD-Regress-ID: dbad2f5ece839658ef8af3376cb1fb1cabe2e324 - -commit 3a506598fddd3f18f9095af3fe917f24cbdd32e0 -Author: djm@openbsd.org -Date: Mon Oct 30 23:00:25 2023 +0000 - - upstream: move PKCS#11 setup code to test-exec.sh so it can be reused + Joint work with markus@ feedback deraadt@ - elsewhere + Tested in snaps since last week - OpenBSD-Regress-ID: 1d29e6be40f994419795d9e660a8d07f538f0acb + OpenBSD-Commit-ID: 9c3b2087ae08626ec31b4177b023db600e986d9c -commit f82fa227a52661c37404a6d33bbabf14fed05db0 +commit fe6c6330c1a94c7a537efe9069853ce7a275c50a Author: djm@openbsd.org -Date: Mon Oct 30 17:32:00 2023 +0000 +Date: Sun Oct 13 22:20:06 2024 +0000 - upstream: tidy and refactor PKCS#11 setup code + upstream: don't start the ObscureKeystrokeTiming mitigations if - Replace the use of a perl script to delete the controlling TTY with a - SSH_ASKPASS script to directly load the PIN. + there has been traffic on a X11 forwarding channel recently. - Move PKCS#11 setup code to functions in anticipation of it being used - elsewhere in additional tests. + Should fix X11 forwarding performance problems when this setting is + enabled. Patch from Antonio Larrosa via bz3655 - Reduce stdout spam - - OpenBSD-Regress-ID: 07705c31de30bab9601a95daf1ee6bef821dd262 - -commit 3cf698c6d4ffa9be1da55672a3519e2135a6366a -Author: Darren Tucker -Date: Mon Oct 30 21:35:03 2023 +1100 - - Add obsd74 test VM and retire obsd69 and obsd70. - -commit 3e21d58a09894acb38dc69ed615d101131f473d0 -Author: Darren Tucker -Date: Mon Oct 30 18:34:12 2023 +1100 + OpenBSD-Commit-ID: 820284a92eb4592fcd3d181a62c1b86b08a4a7ab - Add OpenSSL 3.3.0 as a known dev version. - -commit 917ba181c2cbdb250a443589ec732aa36fd51ffa -Author: Darren Tucker -Date: Mon Oct 30 13:32:03 2023 +1100 +commit 538cd28598ae942c94b99855b06fdd937e2e7381 +Author: jsg@openbsd.org +Date: Sat Oct 12 10:50:37 2024 +0000 - Restore nopasswd sudo rule on Mac OS X. + upstream: remove duplicate misc.h include ok dtucker@ - This seems to be missing from some (but not all) github runners, so - restore it if it seems to be missing. + OpenBSD-Commit-ID: fdd056e7854294834d54632b4282b877cfe4c12e -commit c5698abad6d4ec98ca20bcaaabaeacd5e1ec3f4f -Author: Darren Tucker -Date: Mon Oct 30 13:26:52 2023 +1100 +commit 0051381a8c33740a77a1eca6859efa1c78887d80 +Author: djm@openbsd.org +Date: Sun Oct 6 23:37:17 2024 +0000 - Don't exit early when setting up on Mac OS X. + upstream: Turn off finite field (a.k.a modp) Diffie-Hellman key - We probably need some of the other bits in there (specifically, setting - the perms on the home directory) so make it less of a special snowflake. - -commit 1d6a878ceba60b9dc14037dddc8f036070c0065f -Author: dtucker@openbsd.org -Date: Sun Oct 29 06:22:07 2023 +0000 - - upstream: Only try to chown logfiles that exist to prevent spurious + exchange in sshd by default. Specifically, this removes the + diffie-hellman-group* and diffie-hellman-group-exchange-* methods. The client + is unchanged and continues to support these methods by default. - errors. + Finite field Diffie Hellman is slow and computationally expensive for + the same security level as Elliptic Curve DH or PQ key agreement while + offering no redeeming advantages. - OpenBSD-Regress-ID: f1b20a476734e885078c481f1324c9ea03af991e - -commit e612376427a66f835e284f6b426d16d7c85301bc -Author: anton@openbsd.org -Date: Thu Oct 26 18:52:45 2023 +0000 - - upstream: make use of bsd.regress.mk in extra and interop targets; ok + ECDH has been specified for the SSH protocol for 15 years and some + form of ECDH has been the default key exchange in OpenSSH for the last + 14 years. - dtucker@ + ok markus@ - OpenBSD-Regress-ID: 7ea21b5f6fc4506165093b2123d88d20ff13a4f0 + OpenBSD-Commit-ID: 4e238ad480a33312667cc10ae0eb6393abaec8da -commit ea0039173957d0edcd6469b9614dcedb44dcb4f9 -Author: dtucker@openbsd.org -Date: Thu Oct 26 12:44:07 2023 +0000 +commit 67a115e7a56dbdc3f5a58c64b29231151f3670f5 +Author: djm@openbsd.org +Date: Thu Sep 26 23:55:08 2024 +0000 - upstream: Skip conch interop tests when not enabled instead of fatal. + upstream: fix previous change to ssh_config Match, which broken on + + negated Matches; spotted by phessler@ ok deraadt@ - OpenBSD-Regress-ID: b0abf81c24ac6c21f367233663228ba16fa96a46 + OpenBSD-Commit-ID: b1c6acec66cd5bd1252feff1d02ad7129ced37c7 -commit d220b9ed5494252b26b95f05be118472bc3ab5c0 -Author: dtucker@openbsd.org -Date: Wed Oct 25 05:38:08 2023 +0000 +commit 220b6c1290042acd5180d783dea01efe1365c265 +Author: jsg@openbsd.org +Date: Wed Sep 25 23:01:39 2024 +0000 - upstream: Import regenerated moduli. + upstream: remove some unused defines; ok djm@ - OpenBSD-Commit-ID: 95f5dd6107e8902b87dc5b005ef2b53f1ff378b8 + OpenBSD-Commit-ID: 3a63e4e11d455704f684c28715d61b17f91e0996 -commit a611e4db4009447a0151f31a44e235ca32ed4429 -Author: anton@openbsd.org -Date: Wed Oct 25 08:01:59 2023 +0000 +commit 3ef4f6e8a4d774f73852391fdccbb95f39fc71bf +Author: jmc@openbsd.org +Date: Wed Sep 25 06:13:01 2024 +0000 - upstream: ssh conch interop tests requires a controlling terminal; + upstream: remove some unneeded Xo/Xc calls; from evan silberman the - ok dtucker@ + original diff had a couple of errors, which i've fixed - OpenBSD-Regress-ID: cbf2701bc347c2f19d907f113779c666f1ecae4a + OpenBSD-Commit-ID: f37ad5888adbc0d4e1cd6b6de237841f4b1e650d -commit da951b5e08c167acb5d6e2eec6f146502f5d6ed8 -Author: anton@openbsd.org -Date: Mon Oct 23 11:30:49 2023 +0000 +commit 3f02368e8e9121847727c46b280efc280e5eb615 +Author: djm@openbsd.org +Date: Wed Sep 25 01:24:04 2024 +0000 - upstream: Use private key that is allowed by sshd defaults in conch + upstream: fix regression introduced when I switched the "Match" + + criteria tokeniser to a more shell-like one. Apparently the old tokeniser + (accidentally?) allowed "Match criteria=argument" as well as the "Match + criteria argument" syntax that we tested for. - interop tests. + People were using this syntax so this adds back support for + "Match criteria=argument" - ok dtucker@ + bz3739 ok dtucker - OpenBSD-Regress-ID: 3b7f65c8f409c328bcd4b704f60cb3d31746f045 + OpenBSD-Commit-ID: d1eebedb8c902002b75b75debfe1eeea1801f58a -commit 1ca166dbb3c0ce632b98869cd955f69320aa6fe8 -Author: Darren Tucker -Date: Fri Oct 20 20:43:00 2023 +1100 +commit 9517cc58577f85a0ba5f8bb46778dff625f0688f +Author: djm@openbsd.org +Date: Tue Sep 24 02:28:17 2024 +0000 - Install Dropbear for interop testing. + upstream: some extra paranoia, reminded by jsg@ + + OpenBSD-Commit-ID: 22072bfa1df1391858ae7768a6c627e08593a91e -commit f993bb58351c5cb71e61aede63805a34a6d4daea -Author: Darren Tucker -Date: Fri Oct 20 20:39:03 2023 +1100 +commit 815a94e86a68c1000b8310cb47695cea9329516c +Author: Damien Miller +Date: Wed Sep 25 11:15:45 2024 +1000 - Resync PuTTY and Conch path handling with upstream. + gss-serv.c needs sys/param.h - Now that configure finds these for us we can remove these -portable - specific changes. + From Void Linux -commit ff85becd5f5f06a76efa45d30fb204a3c5e5215c -Author: Darren Tucker -Date: Fri Oct 20 20:35:46 2023 +1100 +commit 76a618d2842c34c16cd21a4efc7230e2f459008d +Author: Damien Miller +Date: Wed Sep 25 11:13:05 2024 +1000 - Have configure find PuTTY and Conch binaries. + build construct_utmp() when USE_BTMP is set - This will let us remove some -portable specific changes from - test-exec.sh. + Fixes compile error on Void Linux/Musl -commit c54a50359b9cecddbf3ffcdc26efcb3cd6071ec1 -Author: dtucker@openbsd.org -Date: Fri Oct 20 07:37:07 2023 +0000 +commit d3aee17f6d395202eaa42a0c449b6da41f61527c +Author: Darren Tucker +Date: Tue Sep 24 18:41:44 2024 +1000 - upstream: Allow overriding the locations of the Dropbear binaries - - similar to what we do for the PuTTY ones. - - OpenBSD-Regress-ID: 7de0e00518fb0c8fdc5f243b7f82f523c936049c + Test the flags from OpenWRT's package. -commit fbaa707d455a61d0aef8ae65e02a25bac5351e5c -Author: dtucker@openbsd.org -Date: Fri Oct 20 06:56:45 2023 +0000 +commit 0f5d19e6fe4b58a89e6dc8c71a2aae30365d193e +Author: Christoph Ostarek +Date: Wed Jul 3 12:46:59 2024 +0200 - upstream: Add interop test with Dropbear. - - Right now this is only dbclient not the Dropbear server since it won't - currently run as a ProxyCommand. + fix utmpx ifdef - OpenBSD-Regress-ID: 8cb898c414fcdb252ca6328896b0687acdaee496 + 02e16ad95fb1f56ab004b01a10aab89f7103c55d did a copy-paste for + utmpx, but forgot to change the ifdef appropriately -commit c2003d0dbdcdb61ca336c3f90c5c2b4a09c8e73f -Author: Fabio Pedretti -Date: Mon Oct 16 11:59:53 2023 +0200 +commit e03239f999acf9dc3da0f2f72bde36abbe678911 +Author: jsg@openbsd.org +Date: Sun Sep 22 12:56:21 2024 +0000 - Update openssl-devel dependency in RPM spec. + upstream: remove some unused defines; ok djm@ - Since openssh 9.4p1, openssl >= 1.1.1 is required, so - build with --without-openssl elsewhere. - According to https://repology.org/project/openssl/versions - openssl 1.1.1 is available on fedora >= 29 and rhel >= 8. - Successfully build tested, installed and run on rhel 6 + OpenBSD-Commit-ID: 81869ee6356fdbff19dae6ff757095e6b24de712 -commit 064e09cd632721c7e6889904e07767443ee23821 -Author: Fabio Pedretti -Date: Mon Oct 16 10:13:06 2023 +0200 +commit a35f543d3a6275fef781e515c262d1c687c3bc28 +Author: jsg@openbsd.org +Date: Fri Sep 20 02:00:46 2024 +0000 - Remove reference of dropped sshd.pam.old file + upstream: remove unneeded semicolons; checked by millert@ - The file was removed in openssh 8.8 + OpenBSD-Commit-ID: 3fb621a58e04b759a875ad6a33f35bb57ca80231 -commit 62db354b696b378a164b6e478cb6b0171dcb0c3d -Author: dtucker@openbsd.org -Date: Mon Oct 16 08:40:00 2023 +0000 +commit 1641f2d4d6e05d2147913442864cae546e64f08b +Author: Darren Tucker +Date: Mon Sep 23 20:52:31 2024 +1000 - upstream: Move declaration of "len" into the block where it's used. - - This lets us compile Portable with -Werror with when OpenSSL doesn't have - Ed25519 support. - - OpenBSD-Commit-ID: e02e4b4af351946562a7caee905da60eff16ba29 + Add 9.9 branch to CI status console. -commit 6eee8c972d5901d10e80634a006b4e346b2c8c19 +commit 46d1fb16b20e971b9ac15e86a3d3e350b49c9ad6 Author: Damien Miller -Date: Fri Oct 13 15:15:05 2023 +1100 +Date: Fri Sep 20 08:20:13 2024 +1000 - run t-extra regress tests - - This exposes the t-extra regress tests (including agent-pkcs11.sh) as - a new extra-tests target in the top level Makefile and runs them by - default. ok dtucker@ + update version numbers -commit 637624dbbac13f2bc3c8ec5b15c9d627d07f2935 -Author: Darren Tucker -Date: Thu Oct 12 22:01:23 2023 +1100 +commit 0bdca1f218971b38728a0a129f482476baff0968 +Author: djm@openbsd.org +Date: Thu Sep 19 22:17:44 2024 +0000 - Don't use make -j2. + upstream: openssh-9.9 - While we have 2 cores available on github runners, not using it means - that the most recent log message is the actual failure, rather than - having to search back through the log for it. + OpenBSD-Commit-ID: 303417285f1a73b9cb7a2ae78d3f493bbbe31f98 -commit 971e0cfcfd52ef1d73cf5244074c306a60006e89 -Author: Darren Tucker -Date: Thu Oct 12 16:23:05 2023 +1100 +commit ef2d7f2d3e1b4c9ae71bacf963e76a92ab8be543 +Author: Damien Miller +Date: Wed Sep 18 16:03:23 2024 +1000 - Correct arg order for ED255519 AC_LINK_IFELSE test. + include openbsd-compat/base64.c license in LICENSE -commit c616e64688b2a0c1b4daad69b056099be998d121 -Author: djm@openbsd.org -Date: Thu Oct 12 03:51:08 2023 +0000 +commit 7ef362b989c8d1f7596f557f22e5924b9c08f0ea +Author: Damien Miller +Date: Wed Sep 18 09:01:23 2024 +1000 + + conditionally include mman.h in arc4random code + +commit 5fb2b5ad0e748732a27fd8cc16a7ca3c21770806 +Author: Damien Miller +Date: Tue Sep 17 11:53:24 2024 +1000 - upstream: typos and extra debug trace calls + fix bug in recently-added sntrup761 fuzzer - OpenBSD-Regress-ID: 98a2a6b9333743274359e3c0f0e65cf919a591d1 + key values need to be static to persist across invocations; + spotted by the Qualys Security Advisory team. -commit c49a3fbf10162128c67c59562348de2041188974 +commit 0ca128c9ee894f1b0067abd473bfb33171df67f8 Author: djm@openbsd.org -Date: Thu Oct 12 03:48:53 2023 +0000 +Date: Mon Sep 16 05:37:05 2024 +0000 - upstream: ensure logs are owned by correct user; feedback/ok + upstream: use 64 bit math to avoid signed underflow. upstream code - dtucker@ + relies on using -fwrapv to provide defined over/underflow behaviour, but we + use -ftrapv to catch integer errors and abort the program. ok dtucker@ - OpenBSD-Regress-ID: c3297af8f07717f1d400a5d34529962f1a76b5a3 + OpenBSD-Commit-ID: 8933369b33c17b5f02479503d0a92d87bc3a574b -commit 5ec0ed79ac074c3437b25f6cba8b8cf21c8d4587 -Author: djm@openbsd.org -Date: Thu Oct 12 03:36:32 2023 +0000 +commit f82e5e22cad88c81d8a117de74241328c7b101c3 +Author: jmc@openbsd.org +Date: Sun Sep 15 08:27:38 2024 +0000 - upstream: 64 %-expansion keys ought to be enough for anybody; ok - - dtucker (we just hit the previous limit in some cases) + upstream: minor grammar/sort fixes for refuseconnection; ok djm - OpenBSD-Commit-ID: 84070f8001ec22ff5d669f836b62f206e08c5787 + OpenBSD-Commit-ID: 1c81f37b138b8b66abba811fec836388a0f3e6da + +commit 0c1165fc78e8fe69b5df71f81a8f944554a68b53 +Author: Damien Miller +Date: Sun Sep 15 13:30:13 2024 +1000 -commit f59a94e22e46db2c23eddeb871aa9e8d93ab0016 + avoid gcc warning in fuzz test + +commit ce171d0718104b643854b53443ff72f7283d33f2 Author: djm@openbsd.org -Date: Thu Oct 12 02:48:43 2023 +0000 +Date: Sun Sep 15 03:09:44 2024 +0000 - upstream: don't dereference NULL pointer when hashing jumphost + upstream: bad whitespace in config dump output - OpenBSD-Commit-ID: 251c0263e1759a921341c7efe7f1d4c73e1c70f4 + OpenBSD-Commit-ID: d899c13b0e8061d209298eaf58fe53e3643e967c -commit 281c79168edcc303abfd5bca983616eaa24c5f32 +commit 671c440786a5a66216922f15d0007b60f1e6733f Author: Damien Miller -Date: Thu Oct 12 13:20:01 2023 +1100 +Date: Sun Sep 15 12:53:59 2024 +1000 - Solaris: prefer PRIV_XPOLICY to PRIV_LIMIT + use construct_utmp to construct btmp records - If the system support PRIV_XPOLICY and one is set, then don't - modify PRIV_LIMIT. bz2833, patch from Ron Jordan, ok dtucker@ + Simpler and removes some code with the old-style BSD license. -commit 98fc34df837f3a3b79d2a111b96fe8a39adcab55 +commit 930cb02b6113df72fbc732b9feb8e4f490952a81 Author: djm@openbsd.org -Date: Thu Oct 12 02:18:18 2023 +0000 +Date: Sun Sep 15 02:20:51 2024 +0000 - upstream: add %j token that expands to the configured ProxyJump + upstream: update the Streamlined NTRU Prime code from the "ref" - hostname (or the empty string if this option is not being used). bz3610, ok - dtucker + implementation in SUPERCOP 20201130 to the "compact" implementation in + SUPERCOP 20240808. The new version is substantially faster. Thanks to Daniel + J Bernstein for pointing out the new implementation (and of course for + writing it). + + tested in snaps/ok deraadt@ - OpenBSD-Commit-ID: ce9983f7efe6a178db90dc5c1698df025df5e339 + OpenBSD-Commit-ID: bf1a77924c125ecdbf03e2f3df8ad13bd3dafdcb -commit 7f3180be8a85320b5d3221714b40c16e66881249 +commit 9306d6017e0ce5dea6824c29ca5ba5673c2923ad Author: djm@openbsd.org -Date: Thu Oct 12 02:15:53 2023 +0000 +Date: Sun Sep 15 01:19:56 2024 +0000 - upstream: release GSS OIDs only at end of authentication; bz2982, - - ok dtucker@ + upstream: document Match invalid-user - OpenBSD-Commit-ID: 0daa41e0525ae63cae4483519ecaa37ac485d94c + OpenBSD-Commit-ID: 2c84a9b517283e9711e2812c1f268081dcb02081 -commit a612b93de5d86e955bfb6e24278f621118eea500 +commit 0118a4da21147a88a56dc8b90bbc2849fefd5c1e Author: djm@openbsd.org -Date: Thu Oct 12 02:12:53 2023 +0000 +Date: Sun Sep 15 01:18:26 2024 +0000 - upstream: mask SIGINT/TERM/QUIT/HUP before checking quit_pending + upstream: add a "Match invalid-user" predicate to sshd_config Match + + options. - and use ppoll() to unmask them in the mainloop. Avoids race condition between - signaling ssh to exit and polling. bz3531; ok dtucker + This allows writing Match conditions that trigger for invalid username. + E.g. + + PerSourcePenalties refuseconnection:90s + Match invalid-user + RefuseConnection yes + + Will effectively penalise bots try to guess passwords for bogus accounts, + at the cost of implicitly revealing which accounts are invalid. + + feedback markus@ - OpenBSD-Commit-ID: 5c14e1aabcddedb95cdf972283d9c0d5083229e7 + OpenBSD-Commit-ID: 93d3a46ca04bbd9d84a94d1e1d9d3a21073fbb07 -commit 531b27a006116fe7aff325510aaa576f24844452 +commit 7875975136f275619427604900cb0ffd7020e845 Author: djm@openbsd.org -Date: Wed Oct 11 23:23:58 2023 +0000 +Date: Sun Sep 15 01:11:26 2024 +0000 - upstream: sync usage() with ssh.1; spotted by kn@ + upstream: Add a "refuseconnection" penalty class to sshd_config + + PerSourcePenalties + + This allows penalising connection sources that have had connections + dropped by the RefuseConnection option. ok markus@ - OpenBSD-Commit-ID: 191a85639477dcb5fa1616d270d93b7c8d5c1dfd + OpenBSD-Commit-ID: 3c8443c427470bb3eac1880aa075cb4864463cb6 -commit 64f7ca881b19be754425dca60d1590d306c9d1d0 +commit 8d21713b669b8516ca6d43424a356fccc37212bb Author: djm@openbsd.org -Date: Wed Oct 11 23:14:33 2023 +0000 +Date: Sun Sep 15 01:09:40 2024 +0000 - upstream: ssh -Q does not make sense with other command-line options, + upstream: Add a sshd_config "RefuseConnection" option - so give it its own line in the manpage + If set, this will terminate the connection at the first authentication + request (this is the earliest we can evaluate sshd_config Match blocks) + + ok markus@ - OpenBSD-Commit-ID: 00a747f0655c12122bbb77c2796be0013c105361 + OpenBSD-Commit-ID: 43cc2533984074c44d0d2f92eb93f661e7a0b09c -commit a752a6c0e1001f93696d7025f0c867f0376e2ecf +commit acad117e66018fe1fa5caf41b36e6dfbd61f76a1 Author: djm@openbsd.org -Date: Wed Oct 11 22:42:26 2023 +0000 +Date: Sun Sep 15 00:58:01 2024 +0000 - upstream: add ChannelTimeout support to the client, mirroring the + upstream: switch sshd_config Match processing to the argv tokeniser - same option in the server. ok markus@ + too; ok markus@ - OpenBSD-Commit-ID: 55630b26f390ac063980cfe7ad8c54b03284ef02 + OpenBSD-Commit-ID: b74b5b0385f2e0379670e2b869318a65b0bc3923 -commit 76e91e7238cdc5662bc818e2a48d466283840d23 +commit baec3f7f4c60cd5aa1bb9adbeb6dfa4a172502a8 Author: djm@openbsd.org -Date: Wed Oct 11 22:41:05 2023 +0000 +Date: Sun Sep 15 00:57:36 2024 +0000 - upstream: add support for reading ED25519 private keys in PEM PKCS8 + upstream: switch "Match" directive processing over to the argv - format; ok markus@ tb@ + string tokeniser, making it possible to use shell-like quoting in Match + directives, particularly "Match exec". ok markus@ - OpenBSD-Commit-ID: 01b85c91757e6b057e9b23b8a23f96415c3c7174 + OpenBSD-Commit-ID: 0877309650b76f624b2194c35dbacaf065e769a5 -commit fc77c8e352c0f44125425c05265e3a00c183d78a +commit dd424d7c382c2074ab70f1b8ad4f169a10f60ee7 Author: djm@openbsd.org -Date: Wed Oct 11 06:40:54 2023 +0000 +Date: Sun Sep 15 00:47:01 2024 +0000 - upstream: mention "none" is a valid argument to IdentityFile; bz3080 + upstream: include pathname in some of the ssh-keygen passphrase + + prompts. Helps the user know what's going on when ssh-keygen is invoked via + other tools. Requested in GHPR503 - OpenBSD-Commit-ID: 1b4fb590ef731099349a7d468b77f02b240ac926 + OpenBSD-Commit-ID: 613b0bb6cf845b7e787d69a5b314057ceda6a8b6 -commit c97520d23d1fe53d30725a2af25d2dddd6f2faff +commit 62bbf8f825cc390ecb0523752ddac1435006f206 Author: djm@openbsd.org -Date: Wed Oct 11 05:42:08 2023 +0000 +Date: Sun Sep 15 00:41:18 2024 +0000 - upstream: in olde rcp/scp protocol mode, when rejecting a path from the + upstream: Do not apply authorized_keys options when signature + + verification fails. Prevents restrictive key options being incorrectly + applied to subsequent keys in authorized_keys. bz3733, ok markus@ - server as not matching the glob that the client sent, log (at debug level) - the received pathname as well as the list of possible expected paths expanded - from the glob. bz2966 + OpenBSD-Commit-ID: ba3776d9da4642443c19dbc015a1333622eb5a4e + +commit 49f325fd47af4e53fcd7aafdbcc280e53f5aa5ce +Author: Wu Weixin +Date: Fri Aug 2 22:16:40 2024 +0800 + + Fix without_openssl always being set to 1 - OpenBSD-Commit-ID: 0bd8db8a595334ca86bca8f36e23fc0395315765 + In Fedora systems, %{?rhel} is empty. In RHEL systems, %{?fedora} is + empty. Therefore, the original code always sets without_openssl to 1. -commit 208c2b719879805983398160791d6a1ef9c2c3fc +commit c21c3a2419bbc1c59cb1a16ea356e703e99a90d9 Author: djm@openbsd.org -Date: Wed Oct 11 04:46:29 2023 +0000 +Date: Thu Sep 12 00:36:27 2024 +0000 - upstream: s/%.100s/%s/ in SSH- banner construction as there's no + upstream: Relax absolute path requirement back to what it was prior to - reason to limit its size: the version string bring included is a compile time - constant going into an allocated banner string. + OpenSSH 9.8, which incorrectly required that sshd was started with an + absolute path in inetd mode. bz3717, patch from Colin Wilson - OpenBSD-Commit-ID: 0ef73304b9bf3e534c60900cd84ab699f859ebcd + OpenBSD-Commit-ID: 25c57f22764897242d942853f8cccc5e991ea058 -commit 0354790826b97c41bbd171a965574e159b58d83e -Author: tb@openbsd.org -Date: Tue Oct 10 06:49:54 2023 +0000 +commit 1bc426f51b0a5cfdcfbd205218f0b6839ffe91e9 +Author: naddy@openbsd.org +Date: Mon Sep 9 14:41:21 2024 +0000 - upstream: Garbage collect cipher_get_keyiv_len() + upstream: document the mlkem768x25519-sha256 key exchange algorithm - This is a compat20 leftover, unused since 2017. + OpenBSD-Commit-ID: fa18dccdd9753dd287e62ecab189b3de45672521 + +commit 0a2db61a5ffc64d2e2961c52964f933879952fc7 +Author: Darren Tucker +Date: Tue Sep 10 21:11:14 2024 +1000 + + Spell omnios test host correctly. + +commit 059ed698a47c9af541a49cf754fd09f984ac5a21 +Author: Darren Tucker +Date: Tue Sep 10 18:52:02 2024 +1000 + + Add omnios test target. + +commit f4ff91575a448b19176ceaa8fd6843a25f39d572 +Author: Darren Tucker +Date: Tue Sep 10 18:45:55 2024 +1000 + + Wrap stdint.h in ifdef. + +commit ff714f001d20a9c843ee1fd9d92a16d40567d264 +Author: Darren Tucker +Date: Mon Sep 9 19:31:54 2024 +1000 + + Also test PAM on dfly64. + +commit 509b757c052ea969b3a41fc36818b44801caf1cf +Author: Damien Miller +Date: Mon Sep 9 21:50:14 2024 +1000 + + stubs for ML-KEM KEX functions - ok djm + used for C89 compilers + +commit 273581210c99ce7275b8efdefbb9f89e1c22e341 +Author: Damien Miller +Date: Mon Sep 9 17:30:38 2024 +1000 + + declare defeat trying to detect C89 compilers - OpenBSD-Commit-ID: 91fa5497c9dc6883064624ac27813a567883fdce + I can't find a reliable way to detect the features the ML-KEM code + requires in configure. Give up for now and use VLA support (that we + can detect) as a proxy for "old compiler" and turn off ML-KEM if + it isn't supported. -commit 8d29ee4115001a02641386ae394992c65ed279e0 -Author: djm@openbsd.org -Date: Tue Oct 10 03:57:45 2023 +0000 +commit e8a0f19b56dfa20f98ea9876d7171ec315fb338a +Author: Damien Miller +Date: Mon Sep 9 16:46:40 2024 +1000 - upstream: Reserve a range of "local extension" message numbers that + fix previous; check for C99 compound literals - OpenSSH promises not to use (comment change only) + The previous commit was incorrect (or at least insufficient), the + ML-KEM code is actually using compound literals, so test for them. + +commit 7c07bec1446978bebe0780ed822c8fedfb377ae8 +Author: Damien Miller +Date: Mon Sep 9 16:06:21 2024 +1000 + + test for compiler feature needed for ML-KEM - OpenBSD-Commit-ID: e61795b453d4892d2c99ce1039112c4a00250e03 + The ML-KEM implementation we uses need the compiler to support + C99-style named struct initialisers (e.g foo = {.bar = 1}). We + still support (barely) building OpenSSH with older compilers, so + add a configure test for this. -commit 90b0d73d63a706e85f6431f05a62d2ce1b476472 +commit d469d5f348772058789d35332d1ccb0b109c28ef Author: djm@openbsd.org -Date: Fri Oct 6 03:32:15 2023 +0000 +Date: Mon Sep 9 03:13:39 2024 +0000 - upstream: typo in error message + upstream: test mlkem768x25519-sha256 - OpenBSD-Regress-ID: 6a8edf0dc39941298e3780b147b10c0a600b4fee + OpenBSD-Regress-ID: 7baf6bc39ae55648db1a2bfdc55a624954847611 -commit e84517f51532ec913d8fb01a8aab7307134774bb +commit 62fb2b51bb7f6863c3ab697f397b2068da1c993f Author: djm@openbsd.org -Date: Fri Oct 6 03:25:14 2023 +0000 +Date: Mon Sep 9 02:39:57 2024 +0000 - upstream: Perform the softhsm2 setup as discrete steps rather than - - as a long shell pipeline. Makes it easier to figure out what has happened - when it breaks. + upstream: pull post-quantum ML-KEM/x25519 key exchange out from - OpenBSD-Regress-ID: b3f1292115fed65765d0a95414df16e27772d81c - -commit cb54becff4d776238e0e9072943ba0872260535d -Author: claudio@openbsd.org -Date: Sun Sep 24 08:14:13 2023 +0000 - - upstream: REGRESS_FAIL_EARLY defaults to yes now. So no need to + compile-time flag now than an IANA codepoint has been assigned for the + algorithm. - overload the value here anymore. OK tb@ bluhm@ + Add mlkem768x25519-sha256 in 2nd KexAlgorithms preference slot. - OpenBSD-Regress-ID: f063330f1bebbcd373100afccebc91a965b14496 - -commit f01f5137ceba65baf34ceac5a298c12ac01b1fef -Author: jmc@openbsd.org -Date: Wed Oct 4 05:42:10 2023 +0000 - - upstream: spelling fix; + ok markus@ - OpenBSD-Commit-ID: 493f95121567e5ab0d9dd1150f873b5535ca0195 - -commit 80a2f64b8c1d27383cc83d182b73920d1e6a91f1 -Author: Damien Miller -Date: Wed Oct 4 15:34:10 2023 +1100 - - crank version numbers + OpenBSD-Commit-ID: 9f50a0fae7d7ae8b27fcca11f8dc6f979207451a -commit f65f187b105d9b5c12fd750a211397d08c17c6d4 +commit a8ad7a2952111c6ce32949a775df94286550af6b Author: djm@openbsd.org -Date: Wed Oct 4 04:04:09 2023 +0000 +Date: Fri Sep 6 02:30:44 2024 +0000 - upstream: openssh-9.5 + upstream: make parsing user@host consistently look for the last '@' in + + the string rather than the first. This makes it possible to use usernames + that contain '@' characters. + MIME-Version: 1.0 + Content-Type: text/plain; charset=UTF-8 + Content-Transfer-Encoding: 8bit - OpenBSD-Commit-ID: 5e0af680480bd3b6f5560cf840ad032d48fd6b16 + Prompted by Max Zettlmeißl; feedback/ok millert@ + + OpenBSD-Commit-ID: 0b16eec246cda15469ebdcf3b1e2479810e394c5 -commit ffe27e54a4bb18d5d3bbd3f4cc93a41b8d94dfd2 +commit 13cc78d016b67a74a67f1c97c7c348084cd9212c Author: djm@openbsd.org -Date: Wed Oct 4 04:03:50 2023 +0000 +Date: Wed Sep 4 05:33:34 2024 +0000 - upstream: add some cautionary text about % token expansion and + upstream: be more strict in parsing key type names. Only allow + + shortnames (e.g "rsa") in user-interface code and require full SSH protocol + names (e.g. "ssh-rsa") everywhere else. - shell metacharacters; based on report from vinci AT protonmail.ch + Prompted by bz3725; ok markus@ - OpenBSD-Commit-ID: aa1450a54fcee2f153ef70368d90edb1e7019113 + OpenBSD-Commit-ID: b3d8de9dac37992eab78adbf84fab2fe0d84b187 -commit 60ec3d54fd1ebfe2dda75893fa1e870b8dffbb0d +commit ef8472309a68e319018def6f8ea47aeb40d806f5 Author: djm@openbsd.org -Date: Tue Oct 3 23:56:10 2023 +0000 +Date: Wed Sep 4 05:11:33 2024 +0000 - upstream: fix link to agent draft; spotted by Jann Horn + upstream: fix RCSID in output - OpenBSD-Commit-ID: ff5bda21a83ec013db683e282256a85201d2dc4b + OpenBSD-Commit-ID: 889ae07f2d2193ddc4351711919134664951dd76 -commit 12e2d4b13f6f63ce2de13cbfcc9e4d0d4b4ab231 -Author: Damien Miller -Date: Wed Oct 4 10:54:04 2023 +1100 +commit ba2ef20c75c5268d4d1257adfc2ac11c930d31e1 +Author: jmc@openbsd.org +Date: Tue Sep 3 06:17:48 2024 +0000 - use portable provider allowlist path in manpage + upstream: envrionment -> environment; - spotted by Jann Horn + OpenBSD-Commit-ID: b719f39c20e8c671ec6135c832d6cc67a595af9c -commit 6c2c6ffde75df95fd838039850d3dd3d84956d87 -Author: deraadt@openbsd.org -Date: Tue Sep 19 20:37:07 2023 +0000 +commit e66c0c5673a4304a3a9fbf8305c6a19f8653740f +Author: Damien Miller +Date: Wed Sep 4 15:35:29 2024 +1000 - upstream: typo; from Jim Spath - - OpenBSD-Commit-ID: 2f5fba917b5d4fcf93d9e0b0756c7f63189e228e + add basic fuzzers for our import of sntrup761 -commit b6b49130a0089b297245ee39e769231d7c763014 +commit d19dea6330ecd4eb403fef2423bd7e127f4c9828 Author: djm@openbsd.org -Date: Sun Sep 10 23:12:32 2023 +0000 +Date: Tue Sep 3 05:58:56 2024 +0000 - upstream: rename remote_glob() -> sftp_glob() to match other API + upstream: regression test for Include variable expansion - OpenBSD-Commit-ID: d9dfb3708d824ec02970a84d96cf5937e0887229 + OpenBSD-Regress-ID: 35477da3ba1abd9ca64bc49080c50a9c1350c6ca -commit 21b79af6c8d2357c822c84cef3fbdb8001ed263b +commit 8c4d6a628051e318bae2f283e8dc38b896400862 Author: djm@openbsd.org -Date: Sun Sep 10 03:51:55 2023 +0000 +Date: Tue Sep 3 05:29:55 2024 +0000 - upstream: typo in comment + upstream: allow the "Include" directive to expand the same set of - OpenBSD-Commit-ID: 69285e0ce962a7c6b0ab5f17a293c60a0a360a18 - -commit 41232d25532b4d2ef6c5db62efc0cf50a79d26ca -Author: Darren Tucker -Date: Sun Sep 10 15:45:38 2023 +1000 - - Use zero-call-used-regs=used with Apple compilers. + %-tokens that "Match Exec" and environment variables. + + ok dtucker@ - Apple's versions of clang have version numbers that do not match the - corresponding upstream clang versions. Unfortunately, they do still - have the clang-15 zero-call-used-regs=all bug, so for now use the value - that doesn't result in segfaults. We could allowlist future versions - that are known to work. bz#3584 (and probably also our github CI - failures). + OpenBSD-Commit-ID: 12ef521eaa966a9241e684258564f52f1f3c5d37 -commit 90ccc5918ea505bf156c31148b6b59a1bf5d6dc6 +commit 51b82648b6827675fc0cde21175fd1ed8e89aab2 Author: djm@openbsd.org -Date: Sun Sep 10 03:25:53 2023 +0000 +Date: Mon Sep 2 12:18:35 2024 +0000 - upstream: randomise keystroke obfuscation intervals and average - - interval rate. ok dtucker@ + upstream: missing ifdef - OpenBSD-Commit-ID: 05f61d051ab418fcfc4857ff306e420037502382 + OpenBSD-Commit-ID: 85f09da957dd39fd0abe08fe5ee19393f25c2021 -commit bd1b9e52f5fa94d87223c90905c5fdc1a7c32aa6 +commit f68312eb593943127b39ba79a4d7fa438c34c153 Author: djm@openbsd.org -Date: Fri Sep 8 06:34:24 2023 +0000 +Date: Mon Sep 2 12:13:56 2024 +0000 - upstream: fix sizeof(*ptr) instead sizeof(ptr) in realloc (pointer here + upstream: Add experimental support for hybrid post-quantum key exchange - is char**, so harmless); spotted in CID 416964 + ML-KEM768 with ECDH/X25519 from the Internet-draft: + https://datatracker.ietf.org/doc/html/draft-kampanakis-curdle-ssh-pq-ke-03 - OpenBSD-Commit-ID: c61caa4a5a667ee20bb1042098861e6c72c69002 - -commit c4f966482983e18601eec70a1563115de836616f -Author: djm@openbsd.org -Date: Fri Sep 8 06:10:57 2023 +0000 - - upstream: regress test recursive remote-remote directories copies where + This is based on previous patches from markus@ but adapted to use the + final FIPS203 standard ML-KEM using a formally-verified implementation + from libcrux. - the directory contains a symlink to another directory. + Note this key exchange method is still a draft and thus subject to + change. It is therefore disabled by default; set MLKEM=yes to build it. + We're making it available now to make it easy for other SSH + implementations to test against it. - also remove errant `set -x` that snuck in at some point + ok markus@ deraadt@ - OpenBSD-Regress-ID: 1c94a48bdbd633ef2285954ee257725cd7bc456f + OpenBSD-Commit-ID: 02a8730a570b63fa8acd9913ec66353735dea42c -commit 5e1dfe5014ebc194641678303e22ab3bba15f4e5 -Author: djm@openbsd.org -Date: Fri Sep 8 06:10:02 2023 +0000 +commit 05f2b141cfcc60c7cdedf9450d2b9d390c19eaad +Author: Antonio Larrosa +Date: Fri Aug 23 12:21:06 2024 +0200 - upstream: fix recursive remote-remote copies of directories that + Don't skip audit before exitting cleanup_exit - contain symlinks to other directories (similar to bz3611) + This fixes an issue where the SSH_CONNECTION_ABANDON event is not + audited because cleanup_exit overrides the regular _exit too soon and + as a result, failed auth attempts are not logged correctly. - OpenBSD-Commit-ID: 7e19d2ae09b4f941bf8eecc3955c9120171da37f + The problem was introduced in 81c1099d22b81ebfd20a334ce986c4f753b0db29 + where the code from upstream was merged before the audit_event call when + it should have been merged right before the _exit call in order to honor + the comment that just mentions an override of the exit value. -commit 7c0ce2bf98b303b6ad91493ee3247d96c18ba1f6 +commit 16eaf9d401e70996f89f3f417738a8db421aa959 Author: djm@openbsd.org -Date: Fri Sep 8 05:50:57 2023 +0000 +Date: Wed Aug 28 12:08:26 2024 +0000 - upstream: regress test for recursive copies of directories containing + upstream: fix test: -F is the argument to specify a non-default - symlinks to other directories. bz3611, ok dtucker@ + ssh_config, not -f (this is sadly not a new bug) - OpenBSD-Regress-ID: eaa4c29cc5cddff4e72a16bcce14aeb1ecfc94b9 + OpenBSD-Regress-ID: 45a7bda4cf33f2cea218507d8b6a55cddbcfb322 -commit 2de990142a83bf60ef694378b8598706bc654b08 -Author: djm@openbsd.org -Date: Fri Sep 8 05:56:13 2023 +0000 +commit 10ccf611ab8ecba9ce6b0548c5ccd8c1220baf92 +Author: deraadt@openbsd.org +Date: Fri Aug 23 04:51:00 2024 +0000 - upstream: the sftp code was one of my first contributions to - - OpenSSH and it shows - the function names are terrible. - - Rename do_blah() to sftp_blah() to make them less so. + upstream: As defined in the RFC, the SSH protocol has negotiable - Completely mechanical except for sftp_stat() and sftp_lstat() which - change from returning a pointer to a static variable (error-prone) to - taking a pointer to a caller-provided receiver. + compression support (which is requested as the name "zlib"). Compression + starts very early in the session. Relative early in OpenSSH lifetime, privsep + was added to sshd, and this required a shared-memory hack so the two + processes could see what was going on in the dataflow. This shared-memory + hack was soon recognized as a tremendous complexity risk, because it put libz + (which very much trusts it's memory) in a dangerous place, and a new option + ("zlib@openssh.com") was added begins compression after authentication (aka + delayed-compression). That change also permitted removal of the + shared-memory hack. Despite removal from the server, the old "zlib" support + remained in the client, to allow negotiation with non-OpenSSH daemons which + lack the delayed-compression option. This commit deletes support for the + older "zlib" option in the client. It reduces our featureset in a small way, + and encourages other servers to move to a better design. The SSH protocol is + different enough that compressed-key-material attacks like BEAST are + unlikely, but who wants to take the chance? We encourage other ssh servers + who care about optional compression support to add delayed-zlib support. + (Some already do "zlib@openssh.com") ok djm markus - OpenBSD-Commit-ID: eb54d6a72d0bbba4d623e2175cf5cc4c75dc2ba4 + OpenBSD-Commit-ID: 6df986f38e4ab389f795a6e39e7c6857a763ba72 -commit 249d8bd0472b53e3a2a0e138b4c030a31e83346a +commit aee54878255d71bf93aa6e91bbd4eb1825c0d1b9 Author: djm@openbsd.org -Date: Fri Sep 8 05:50:12 2023 +0000 +Date: Thu Aug 22 23:11:30 2024 +0000 - upstream: fix scp in SFTP mode recursive upload and download of + upstream: sntrup761x25519-sha512 now has an IANA codepoint assigned, so - directories that contain symlinks to other directories. In scp mode, the - links would be followed, but in SFTP mode they were not. bz3611, ok dtucker@ + we can make the algorithm available without the @openssh.com suffix too. ok + markus@ deraadt@ - OpenBSD-Commit-ID: 9760fda668eaa94a992250d7670dfbc62a45197c + OpenBSD-Commit-ID: eeed8fcde688143a737729d3d56d20ab4353770f -commit 0e1f4401c466fa4fdaea81b6dadc8dd1fc4cf0af -Author: djm@openbsd.org -Date: Wed Sep 6 23:36:09 2023 +0000 +commit a76a6b85108e3032c8175611ecc5746e7131f876 +Author: Darren Tucker +Date: Thu Aug 22 20:36:12 2024 +1000 - upstream: regression test for override of subsystem in match blocks + Move rekey test into valgrind-2. - OpenBSD-Regress-ID: 5f8135da3bfda71067084c048d717b0e8793e87c + Now that the rekey test has been optimized it's fast enough to not be in + its own valgrind test, so move it into valgrind-2, which is currently + the quickest of the others, bringing all of them to roughly the same + runtime of ~1.1 hours. -commit 8a1450c62035e834d8a79a5d0d1c904236f9dcfe -Author: djm@openbsd.org -Date: Wed Sep 6 23:35:35 2023 +0000 +commit 7e75e3f57c41b9a6e6401e7674d7c2ff5c33975b +Author: dtucker@openbsd.org +Date: Thu Aug 22 10:21:02 2024 +0000 - upstream: allow override of Sybsystem directives in sshd Match + upstream: Use aes128-ctr for MAC tests since default has implicit MAC. - blocks + Also verify that the Cipher or MAC we intended to use is actually the one + selected during the test. - OpenBSD-Commit-ID: 3911d18a826a2d2fe7e4519075cf3e57af439722 + OpenBSD-Regress-ID: ff43fed30552afe23d1364526fe8cf88cbfafe1d -commit 6e52826e2a74d077147a82ead8d4fbd5b54f4e3b -Author: djm@openbsd.org -Date: Wed Sep 6 23:26:37 2023 +0000 +commit ebc890b8b4ba08c84cd1066b7b94b2b11f6c4cb4 +Author: Damien Miller +Date: Thu Aug 22 09:45:49 2024 +1000 - upstream: allocate the subsystems array as necessary and remove the - - fixed limit of subsystems. Saves a few kb of memory in the server and makes - it more like the other options. + fix incorrect default for PasswordAuthentication - OpenBSD-Commit-ID: e683dfca6bdcbc3cc339bb6c6517c0c4736a547f + merge botch spotted by gsgleason -commit e19069c9fac4c111d6496b19c7f7db43b4f07b4f -Author: djm@openbsd.org -Date: Wed Sep 6 23:23:53 2023 +0000 +commit 15ace435ea1c2fab2a1cc7d9c3157fe20c776b80 +Author: dtucker@openbsd.org +Date: Wed Aug 21 10:33:27 2024 +0000 - upstream: preserve quoting of Subsystem commands and arguments. + upstream: Some awks won't match on the \r so delete it instead. Fixes - This may change behaviour of exotic configurations, but the most common - subsystem configuration (sftp-server) is unlikely to be affected. + regress in portable on, eg Solaris. - OpenBSD-Commit-ID: 8ffa296aeca981de5b0945242ce75aa6dee479bf + OpenBSD-Regress-ID: 44a96d6d2f8341d89b7d5fff777502b92ac9e9ba -commit 52dfe3c72d98503d8b7c6f64fc7e19d685636c0b -Author: djm@openbsd.org -Date: Wed Sep 6 23:21:36 2023 +0000 +commit 51c96b6ed627779a04493a8fe25747996a37f3c2 +Author: dtucker@openbsd.org +Date: Wed Aug 21 07:06:27 2024 +0000 - upstream: downgrade duplicate Subsystem directives from being a - - fatal error to being a debug message to match behaviour with just about all - other directives. + upstream: Import regenerated moduli. - OpenBSD-Commit-ID: fc90ed2cc0c18d4eb8e33d2c5e98d25f282588ce + OpenBSD-Commit-ID: 5db7049ad5558dee5b2079d3422e8ddab187c1cc -commit 1ee0a16e07b6f0847ff463d7b5221c4bf1876e25 -Author: djm@openbsd.org -Date: Wed Sep 6 23:18:15 2023 +0000 +commit 25c52f37a82c4da48ec537de37d7c168982b8d6d +Author: dtucker@openbsd.org +Date: Wed Aug 21 06:59:08 2024 +0000 - upstream: handle cr+lf (instead of just cr) in sshsig signature + upstream: Use curve25519-sha256 kex where possible. - files + Except where we're explicitly testing a different kex, use + curve25519-sha256 since it's faster than the default and supported even + when configured without OpenSSL. Add a check to ensure that the kex we + intended to test is the one we actually tested. Speeds test up by ~5%. - OpenBSD-Commit-ID: 647460a212b916540016d066568816507375fd7f + OpenBSD-Regress-ID: 3b27fcc2ae953cb08fd82a0d3155c498b226d6e0 -commit e1c284d60a928bcdd60bc575c6f9604663502770 -Author: job@openbsd.org -Date: Mon Sep 4 10:29:58 2023 +0000 +commit 3eb62b7ba49483c309b483eb9002a679014f3887 +Author: dtucker@openbsd.org +Date: Tue Aug 20 12:36:59 2024 +0000 - upstream: Generate Ed25519 keys when invoked without arguments - - Ed25519 public keys are very convenient due to their small size. - OpenSSH has supported Ed25519 since version 6.5 (January 2014). + upstream: Send only as much data as needed to trigger rekeying. Speeds - OK djm@ markus@ sthen@ deraadt@ + up tests by about 10% in the common case, hopefully more when instrumented + with something like valgrind. - OpenBSD-Commit-ID: f498beaad19c8cdcc357381a60df4a9c69858b3f + OpenBSD-Regress-ID: 7bf9292b4803357efcf0baf7cfbdc8521f212da1 -commit 694150ad92765574ff82a18f4e86322bd3231e68 -Author: djm@openbsd.org -Date: Mon Sep 4 00:08:14 2023 +0000 +commit cbd3f034bbf7853618fac99d7d868a2250154ea7 +Author: Damien Miller +Date: Wed Aug 21 09:18:29 2024 +1000 - upstream: trigger keystroke timing obfucation only if the channels - - layer enqueud some data in the last poll() cycle; this avoids triggering the - obfuscatior for non-channels data like ClientAlive probes and also fixes a - related problem were the obfucations would be triggered on fully quiescent - connections. - - Based on / tested by naddy@ - - OpenBSD-Commit-ID: d98f32dc62d7663ff4660e4556e184032a0db123 + simplify sshkey_prekey_alloc(); always use mmap -commit b5fd97896b59a3a46245cf438cc8b16c795d9f74 -Author: djm@openbsd.org -Date: Mon Sep 4 00:04:02 2023 +0000 +commit 4442bbc2fc661277a6dabfedb756a7e15ee8b8b8 +Author: dtucker@openbsd.org +Date: Tue Aug 20 09:15:49 2024 +0000 - upstream: avoid bogus "obfuscate_keystroke_timing: stopping ..." + upstream: Merge AEAD test into main test loop. - debug messages when keystroke timing obfuscation was never started; spotted - by naddy@ + Removes 3 duplicate tests and speeds overall test up by about 1%. - OpenBSD-Commit-ID: 5c270d35f7d2974db5c1646e9c64188f9393be31 + OpenBSD-Regress-ID: 5e5c9ff3f7588091ed369e34ac28520490ad2619 -commit ccf7d913db34e49b7a6db1b8331bd402004c840d -Author: djm@openbsd.org -Date: Mon Sep 4 00:01:46 2023 +0000 +commit 829976a63fd1efae3a4c3e7c16fded59d92edb67 +Author: dtucker@openbsd.org +Date: Tue Aug 20 09:02:45 2024 +0000 - upstream: make channel_output_poll() return a flag indicating + upstream: Set a default RekeyLimit of 256k. - whether channel data was enqueued. Will be used to improve keystroke timing - obfuscation. Problem spotted by / tested by naddy@ + Used unless overridden by a command-line flag, which simplifies some of + the ssh command lines. - OpenBSD-Commit-ID: f9776c7b0065ba7c3bbe50431fd3b629f44314d0 + OpenBSD-Regress-ID: e7cffa57027088e10336e412b34113969f88cb87 -commit 43254b326ac6e2131dbd750f9464dc62c14bd5a7 -Author: djm@openbsd.org -Date: Sun Sep 3 23:59:32 2023 +0000 +commit 57d02c9ea36aebad4e7146d46e041b6b2e582f7f +Author: dtucker@openbsd.org +Date: Tue Aug 20 07:52:43 2024 +0000 - upstream: set interactive mode for ControlPersist sessions if they + upstream: Add Compression=no to default ssh_config. - originally requested a tty; enables keystroke timing obfuscation for most - ControlPersist sessions. Spotted by naddy@ + All of the rekey tests use it (otherwise the encrypted byte counts would + not match) so this lets us simplify the command lines. - OpenBSD-Commit-ID: 72783a26254202e2f3f41a2818a19956fe49a772 + OpenBSD-Regress-ID: dab7ce10f4cf6c68827eb8658141272aab3ea262 -commit ff3eda68ceb2e2bb8f48e3faceb96076c3e85c20 -Author: Darren Tucker -Date: Thu Aug 31 23:02:35 2023 +1000 +commit 7254eb26f7c0772c4b47c3b32f6d1b15855cdd8c +Author: dtucker@openbsd.org +Date: Tue Aug 20 07:41:35 2024 +0000 - Set LLONG_MAX for C89 test. + upstream: Remove duplicate curve25519-sha256 kex. - If we don't have LLONG_MAX, configure will figure out that it can get it - by setting -std=gnu99, at which point we won't be testing C89 any more. - To avoid this, feed it in via CFLAGS. - -commit f98031773db361424d59e3301aa92aacf423d920 -Author: djm@openbsd.org -Date: Tue Aug 29 02:50:10 2023 +0000 - - upstream: make PerSourceMaxStartups first-match-wins; ok dtucker@ + curve25519-sha256@libssh.org is the pre-standardization name for the same + thing, so remove it as a duplicate. Speeds up test by a tiny amount. - OpenBSD-Commit-ID: dac0c24cb709e3c595b8b4f422a0355dc5a3b4e7 + OpenBSD-Regress-ID: 5a5ee5fa1595a6e140b1cc16040bedf5996a5715 -commit cfa66857db90cd908de131e0041a50ffc17c7df8 -Author: djm@openbsd.org -Date: Mon Aug 28 09:52:09 2023 +0000 +commit 749896b874928c2785256cae4d75161dc3bfcc7d +Author: dtucker@openbsd.org +Date: Tue Aug 20 07:27:25 2024 +0000 - upstream: descriptive text shouldn't be under .Cm + upstream: Unnest rekey param parsing test and use ssh not sshd. + + ssh uses the same parsing code, now has "-G" to dump its config and is + slightly faster to start up. This speeds up the test slightly (~5%) in the + common case but should help more during instrumented tests, eg under + valgrind, where startup costs are magnified. - OpenBSD-Commit-ID: b1afaeb456a52bc8a58f4f9f8b2f9fa8f6bf651b + OpenBSD-Regress-ID: 07c3acaf4c728e641033071f4441afc88141b0d0 -commit 01dbf3d46651b7d6ddf5e45d233839bbfffaeaec +commit 2b1762115481ff2b7a60fd4db2ae69b725437462 Author: djm@openbsd.org -Date: Mon Aug 28 09:48:11 2023 +0000 +Date: Tue Aug 20 11:10:04 2024 +0000 - upstream: limit artificial login delay to a reasonable maximum (5s) - - and don't delay at all for the "none" authentication mechanism. Patch by - Dmitry Belyavskiy in bz3602 with polish/ok dtucker@ + upstream: actually use the length parameter that was passed in rather - OpenBSD-Commit-ID: 85b364676dd84cf1de0e98fc2fbdcb1a844ce515 - -commit 528da5b9d7c5da01ed7a73ff21c722e1b5326006 -Author: jmc@openbsd.org -Date: Mon Aug 28 05:32:28 2023 +0000 - - upstream: add spacing for punctuation when macro args; + than a constant (this makes no difference in practice because the length is + always the same); reported by martin AT nmkd.net - OpenBSD-Commit-ID: e80343c16ce0420b2aec98701527cf90371bd0db + OpenBSD-Commit-ID: 4aecce232c2fe9b16e9217ff6bcb3c848d853e7e -commit 3867361ca691d0956ef7d5fb8181cf554a91d84a -Author: djm@openbsd.org -Date: Mon Aug 28 04:06:52 2023 +0000 +commit d922762ca16a7381131b242f49d7376c41fabcb5 +Author: Damien Miller +Date: Tue Aug 20 13:55:30 2024 +1000 - upstream: explicit long long type in timing calculations (doesn't - - matter, since the range is pre-clamped) + private key coredump protection for Linux/FreeBSD - OpenBSD-Commit-ID: f786ed902d04a5b8ecc581d068fea1a79aa772de + platforms not supporting coredump exclusion using mmap/madvise flags + fall back to plain old malloc(3). -commit 7603ba71264e7fa938325c37eca993e2fa61272f +commit cc048ca536d6bed6f2285b07040b0d57cd559ba5 Author: djm@openbsd.org -Date: Mon Aug 28 03:31:16 2023 +0000 +Date: Tue Aug 20 03:48:30 2024 +0000 - upstream: Add keystroke timing obfuscation to the client. + upstream: place shielded keys (i.e. keys at rest in RAM) into memory - This attempts to hide inter-keystroke timings by sending interactive - traffic at fixed intervals (default: every 20ms) when there is only a - small amount of data being sent. It also sends fake "chaff" keystrokes - for a random interval after the last real keystroke. These are - controlled by a new ssh_config ObscureKeystrokeTiming keyword/ + allocated using mmap(3) with MAP_CONCEAL set. This prevents exposure of the + key material in coredumps, etc (this is in addition to other measures we take + in this area). - feedback/ok markus@ + ok deraadt@ - OpenBSD-Commit-ID: 02231ddd4f442212820976068c34a36e3c1b15be + OpenBSD-Commit-ID: cbbae59f337a00c9858d6358bc65f74e62261369 -commit dce6d80d2ed3cad2c516082682d5f6ca877ef714 +commit a0b35c791cad1f85481b23ba46373060292e1c80 Author: djm@openbsd.org -Date: Mon Aug 28 03:28:43 2023 +0000 +Date: Sat Aug 17 08:35:04 2024 +0000 - upstream: Introduce a transport-level ping facility - - This adds a pair of SSH transport protocol messages SSH2_MSG_PING/PONG - to implement a ping capability. These messages use numbers in the "local - extensions" number space and are advertised using a "ping@openssh.com" - ext-info message with a string version number of "0". + upstream: mention that ed25519 is the default key type generated and - ok markus@ + clarify that rsa-sha2-512 is the default signature scheme when RSA is in use. + Based on GHPR505 from SebastianRzk - OpenBSD-Commit-ID: b6b3c4cb2084c62f85a8dc67cf74954015eb547f + OpenBSD-Commit-ID: 1d90df71636a04601685d2a10a8233bcc8d4f4c5 -commit d2d247938b38b928f8a6e1a47a330c5584d3a358 -Author: tobhe@openbsd.org -Date: Mon Aug 21 21:16:18 2023 +0000 +commit 127a50f2c80572ed1a021feb11ecf941e92cbbef +Author: djm@openbsd.org +Date: Sat Aug 17 08:23:04 2024 +0000 - upstream: Log errors in kex_exchange_identification() with level - - verbose instead of error to reduce preauth log spam. All of those get logged - with a more generic error message by sshpkt_fatal(). + upstream: fix minor memory leak in Subsystem option parsing; from - feedback from sthen@ - ok djm@ + Antonio Larrosa via GHPR515 - OpenBSD-Commit-ID: bd47dab4695b134a44c379f0e9a39eed33047809 + OpenBSD-Commit-ID: fff3bbefd1b2c45c98cbe45c6b857b15d8a2d364 -commit 9d7193a8359639801193ad661a59d1ae4dc3d302 +commit 171427261d2079941eb1041079dbae875da37cbc Author: djm@openbsd.org -Date: Mon Aug 21 04:59:54 2023 +0000 +Date: Sat Aug 17 08:09:50 2024 +0000 - upstream: correct math for ClientAliveInterval that caused the + upstream: fix swapping of source and destination addresses in some sshd - probes to be sent less frequently than configured; from Dawid Majchrzak + log messages - OpenBSD-Commit-ID: 641153e7c05117436ddfc58267aa267ca8b80038 + OpenBSD-Commit-ID: 24d4cbb86325275df1f037545aa3b91456e52d25 -commit 3c6ab63b383b0b7630da175941e01de9db32a256 +commit 2a50a8f1fa57857a5e124a2280bcf61cc63c77f7 Author: Darren Tucker -Date: Fri Aug 25 14:48:02 2023 +1000 +Date: Sat Aug 17 11:10:19 2024 +1000 - Include Portable version in sshd version string. + Add compat functions for EVP_Digest{Sign,Verify}. - bz#3608, ok djm@ + This should make LibreSSL 3.1.x through 3.3.x work again. Code from + tb@, ok djm@. Restore the test configs covering those. -commit 17fa6cd10a26e193bb6f65d21264d2fe553bcd87 -Author: Darren Tucker -Date: Mon Aug 21 19:47:58 2023 +1000 +commit 1c3a7145260e03037cc18715b883880836fd122d +Author: Philip Hands +Date: Thu Aug 8 13:03:51 2024 +0200 - obsd-arm64 host is real hardware... + make sure that usage & man page match - so put in the correct config location. + SSH-Copy-ID-Upstream: da5b1abe55b72a16e0430e7598e1573da01779c0 -commit 598ca75c85acaaacee5ef954251e489cc20d7be9 -Author: Darren Tucker -Date: Mon Aug 21 18:38:36 2023 +1000 +commit cd0d681645b9adcf2467e7838bfd9d5142de4c4e +Author: Philip Hands +Date: Thu Aug 8 13:01:47 2024 +0200 - Add OpenBSD ARM64 test host. + update copyright notices + + Bump the year to 2024, but also reflect the fact that hands.com Ltd. has + been wound up in the UK, and its assets (including this copyright) have + now reverted to its owner, Philip Hands. + + SSH-Copy-ID-Upstream: 0e4c4d072747a6568b11a790c29dd1b4ce663d7f -commit 1acac79bfbe207e8db639e8043524962037c8feb -Author: Darren Tucker -Date: Mon Aug 21 18:05:26 2023 +1000 +commit 7fc9ccdce18841ebd0a97e31e43258512ab32a32 +Author: Philip Hands +Date: Sun Aug 4 20:45:00 2024 +0200 - Add test for zlib development branch. + restore optionality of -i's argument + + SSH-Copy-ID-Upstream: f70e3abb510e4eeb040b47894e41828246c1b720 -commit 84efebf352fc700e9040c8065707c63caedd36a3 -Author: djm@openbsd.org -Date: Mon Aug 21 04:36:46 2023 +0000 +commit c37aa7012b1a3c2c322fd19e71310aadc90fc674 +Author: Philip Hands +Date: Fri Aug 2 15:52:07 2024 +0200 - upstream: want stdlib.h for free(3) + avoid exploring .ssh/id*.pub subdirectories - OpenBSD-Commit-ID: 743af3c6e3ce5e6cecd051668f0327a01f44af29 + SSH-Copy-ID-Upstream: 0b9e08b7707ad16de3c8e6a0410d9f42fbd56997 -commit cb4ed12ffc332d1f72d054ed92655b5f1c38f621 -Author: Darren Tucker -Date: Sat Aug 19 07:39:08 2023 +1000 +commit 777dce9e2e0d12f7e81e162f77749f30899869fe +Author: Philip Hands +Date: Fri Aug 2 10:07:11 2024 +0200 - Fix zlib version check for 1.3 and future version. + ensure that we're always told the source of keys - bz#3604. + SSH-Copy-ID-Upstream: 1bee96f4793e8ec3fab9f9361204ae58f5cc7cae -commit 25b75e21f16bccdaa472ea1889b293c9bd51a87b -Author: Darren Tucker -Date: Mon Aug 14 11:10:08 2023 +1000 +commit fb94fd2339848e40cad6c9bb42b822244cc1a7bc +Author: Philip Hands +Date: Wed Jul 31 23:19:51 2024 +0200 - Add 9.4 branch to CI status page. + add $HOME to ERROR if one cannot write to ~/.ssh + + SSH-Copy-ID-Upstream: ebef3e9c06e0447bff06e9d84b33023cf592e0ba -commit 803e22eabd3ba75485eedd8b7b44d6ace79f2052 -Author: djm@openbsd.org -Date: Fri Aug 18 01:37:41 2023 +0000 +commit eb5aafa1ffaeee75799141ec5ded406a65ec7d18 +Author: Philip Hands +Date: Wed Jul 31 23:19:03 2024 +0200 - upstream: fix regression in OpenSSH 9.4 (mux.c r1.99) that caused + assert that SCRATCH_DIR is a writable directory - multiplexed sessions to ignore SIGINT under some circumstances. Reported by / - feedback naddy@, ok dtucker@ + SSH-Copy-ID-Upstream: ecb2b9d10883b9a16df56c83896c9bb47a80cde2 + +commit abcc460a2af46f0d812f8433d97a8eae1d80724c +Author: Philip Hands +Date: Wed Jul 31 23:17:54 2024 +0200 + + quote to avoid potential for word splitting - OpenBSD-Commit-ID: 4d5c6c894664f50149153fd4764f21f43e7d7e5a + SSH-Copy-ID-Upstream: f379adbe06ac2ef1daf0f130752234c7f8b97e3c -commit e706bca324a70f68dadfd0ec69edfdd486eed23a -Author: djm@openbsd.org -Date: Wed Aug 16 16:14:11 2023 +0000 +commit b3f91411fd1473605f74c40c1a91a024c7171e27 +Author: Philip Hands +Date: Wed Jul 31 23:15:11 2024 +0200 - upstream: defence-in-depth MaxAuthTries check in monitor; ok markus + ensure ERROR output goes to STDERR - OpenBSD-Commit-ID: 65a4225dc708e2dae71315adf93677edace46c21 + SSH-Copy-ID-Upstream: ac394b05eead3b91feb7c2ae4129a3e9b892f1e2 -commit d1ab7eb90474df656d5e9935bae6df0bd000d343 -Author: djm@openbsd.org -Date: Mon Aug 14 03:37:00 2023 +0000 +commit 674b8f30f0dbacd787eb1e4e7e1ece34b5543d8f +Author: Philip Hands +Date: Thu Aug 1 14:03:06 2024 +0200 - upstream: add message number of SSH2_MSG_NEWCOMPRESS defined in RFC8308 + avoid extra space when no arg given to -i option - OpenBSD-Commit-ID: 6c984171c96ed67effd7b5092f3d3975d55d6028 + SSH-Copy-ID-Upstream: feca9e67e6e37c5653445d1c733569d7abb1770e -commit fa8da52934cb7dff6f660a143276bdb28bb9bbe1 -Author: Darren Tucker -Date: Sun Aug 13 15:01:27 2023 +1000 +commit 0efa0e1c41427c0c6ba839a18c72c1afcd7b7cc0 +Author: Philip Hands +Date: Wed Jul 31 23:28:36 2024 +0200 - Add obsd72 and obsd73 test targets. + put the -i before -[pP] (matching man pages) + + The man pages (ssh, sftp & ssh-copy-id) all list -i before the port + setting, so make the output match that order, which also seems more + natural with the port being next to the server. + + SSH-Copy-ID-Upstream: 34d5d614172c78f9a42249466c4b81975b8883a1 -commit f9f18006678d2eac8b0c5a5dddf17ab7c50d1e9f -Author: djm@openbsd.org -Date: Thu Aug 10 23:05:48 2023 +0000 +commit 87831345e9745f2d13bd7a4a7972809f6788f331 +Author: Shreyas Mahangade +Date: Mon Jul 29 15:26:05 2024 +0000 - upstream: better debug logging of sessions' exit status + Minor space issue fixed - OpenBSD-Commit-ID: 82237567fcd4098797cbdd17efa6ade08e1a36b0 + SSH-Copy-ID-Upstream: 335e44d7be78b03962a54c3a5c99a2ff45294a54 -commit a8c57bcb077f0cfdffcf9f23866bf73bb93e185c -Author: naddy@openbsd.org -Date: Thu Aug 10 14:37:32 2023 +0000 +commit 2f3010f4736b4b3f5c10a4be97a24e90ff04c5e7 +Author: Shreyas Mahangade +Date: Mon Jul 29 16:55:28 2024 +0530 - upstream: drop a wayward comma, ok jmc@ + Show identity file in 'ssh' command - OpenBSD-Commit-ID: 5c11fbb9592a29b37bbf36f66df50db9d38182c6 + - Previously no identity file is shown in "ssh" command output on the line "Now try logging into the..." + - This commit makes sure whenever "ssh-copy-id" with "-i" is invoked, it also reflects in "ssh" command + + SSH-Copy-ID-Upstream: 58e022ec26cb2315eb3be581d01e0ba787082428 -commit e962f9b318a238db1becc53c2bf79dd3a49095b4 +commit a13856374b894397a7682b32257ed0bf67cfede9 Author: Damien Miller -Date: Thu Aug 10 11:10:22 2023 +1000 +Date: Fri Aug 16 08:30:20 2024 +1000 - depend + more OPENSSL_HAS_ECC -commit 0fcb60bf83130dfa428bc4422b3a3ac20fb528af +commit 4da2a1a7f648979bea6eaf3b17f5f250faed4afc Author: Damien Miller -Date: Thu Aug 10 11:05:42 2023 +1000 +Date: Thu Aug 15 23:35:54 2024 +1000 - update versions in RPM specs + fix merge botch that broke !OPENSSL_HAS_ECC -commit d0cee4298491314f09afa1c4383a66d913150b26 +commit 2c53d2f32b8e3992b61682c909ae5bc5122b6e5d Author: Damien Miller -Date: Thu Aug 10 11:05:14 2023 +1000 +Date: Thu Aug 15 15:09:45 2024 +1000 - update version in README + missed OPENSSL_HAS_ECC case -commit 78b4dc6684f4d35943b46b24ee645edfdb9974f5 -Author: djm@openbsd.org -Date: Thu Aug 10 01:01:07 2023 +0000 +commit 342dd7a219f39119b8b686b5aaa99c8e15ede368 +Author: Damien Miller +Date: Thu Aug 15 15:06:55 2024 +1000 - upstream: openssh-9.4 + retire testing aginst older LibreSSL versions + + libressl prior to 3.4.x lack support for the EVP_DigestSign and + EVP_DigestVerify APIs that we need now that sshkey is converted + to EVP_PKEY. - OpenBSD-Commit-ID: 71fc1e01a4c4ea061b252bd399cda7be757e6e35 + If someone makes a good case for why we should support these versions + then we could bring back support with wrappers. -commit 58ca4f0aa8c4306ac0a629c9a85fb1efaf4ff092 -Author: Darren Tucker -Date: Thu Aug 10 11:30:24 2023 +1000 +commit a7c6ea8eebe0f179141ec5dbf0c9e5354417930f +Author: Damien Miller +Date: Thu Aug 15 12:44:17 2024 +1000 - Only include unistd.h once. + sync TEST_MALLOC_OPTIONS for OpenBSD -commit 3961ed02dc578517a9d2535128cff5c3a5460d28 +commit 60c2cf22e8f64f35d8b1175e4671257313f2e4d3 Author: Damien Miller -Date: Thu Aug 10 09:08:49 2023 +1000 +Date: Thu Aug 15 12:43:47 2024 +1000 - wrap poll.h include in HAVE_POLL_H + remove gratuitious difference from OpenBSD -commit e535fbe2af893046c28adfcd787c1fdbae36a24a -Author: dtucker@openbsd.org -Date: Fri Aug 4 06:32:40 2023 +0000 +commit 339c4fc60a6250429d41fa8713f783d82aad4551 +Author: djm@openbsd.org +Date: Thu Aug 15 00:52:23 2024 +0000 - upstream: Apply ConnectTimeout to multiplexing local socket - - connections. If the multiplex socket exists but the connection times out, - ssh will fall back to a direct connection the same way it would if the socket - did not exist at all. ok djm@ + upstream: adapt to EVP_PKEY conversion - OpenBSD-Commit-ID: 2fbe1a36d4a24b98531b2d298a6557c8285dc1b4 + OpenBSD-Regress-ID: 0e2d4efb0ed0e392e23cd8fda183fe56531ac446 -commit 9d92e7b24848fcc605945f7c2e3460c7c31832ce -Author: Darren Tucker -Date: Thu Aug 3 19:35:33 2023 +1000 +commit 63a94f99b9d7c8a48182a40192e45879d1ba8791 +Author: djm@openbsd.org +Date: Fri Jul 19 04:33:36 2024 +0000 - Fix RNG seeding for OpenSSL w/out self seeding. + upstream: test transfers in mux proxy mode too - When sshd is built with an OpenSSL that does not self-seed, it would - fail in the preauth privsep process while handling a new connection. - Sanity checked by djm@ + OpenBSD-Regress-ID: 2edfc980628cfef3550649cab8d69fa23b5cd6c4 -commit f70010d9b0b3e7e95de8aa0b961e1d74362cfb5d +commit 7bdfc20516e288b58c8c847958059c7b141eeff9 Author: djm@openbsd.org -Date: Wed Aug 2 23:04:38 2023 +0000 +Date: Thu Aug 15 00:51:51 2024 +0000 - upstream: CheckHostIP has defaulted to 'no' for a while; make the + upstream: Convert RSA and ECDSA key to the libcrypto EVP_PKEY API. + + DSA remains unconverted as it will be removed within six months. + + Based on patches originally from Dmitry Belyavskiy, but significantly + reworked based on feedback from Bob Beck, Joel Sing and especially + Theo Buehler (apologies to anyone I've missed). - commented- out config option match. From Ed Maste + ok tb@ - OpenBSD-Commit-ID: e66e934c45a9077cb1d51fc4f8d3df4505db58d9 + OpenBSD-Commit-ID: d098744e89f1dc7e5952a6817bef234eced648b5 -commit c88a8788f9865d02b986d00405b9f0be65ad0b5a -Author: dtucker@openbsd.org -Date: Tue Aug 1 08:15:04 2023 +0000 +commit 0af06e2c5b898992a18c74333e75a0136506acc6 +Author: tobias@openbsd.org +Date: Wed Aug 14 15:42:18 2024 +0000 - upstream: remove unnecessary if statement. + upstream: Reorder calloc arguments + + The first argument should be the amount, the second argument should be the + element size. Fixing this also silences some gcc compiler warnings for + portable. + + Spotted with Benny Baumann (BenBE at geshi dot org). - github PR#422 from eyalasulin999, ok djm@ + ok djm@ - OpenBSD-Commit-ID: 2b6b0dde4407e039f58f86c8d2ff584a8205ea55 + OpenBSD-Commit-ID: 711ad6f7bd7fb48bf52208f2cf9f108cddb6d41a -commit 77b8b865cd5a8c79a47605c0c5b2bacf4692c4d5 -Author: jmc@openbsd.org -Date: Fri Jul 28 05:42:36 2023 +0000 +commit 56ce0aa3c6cf28d9fcbce3207457abeac91b5050 +Author: tobias@openbsd.org +Date: Wed Aug 14 15:40:30 2024 +0000 + + upstream: Extend sshbuf validation + + Multiple sshbuf structs can be linked through a parent/child relationship. + Make sure that a single sshbuf cannot be its own parent. If this would ever + happen, it would result in reference counting issues. + + This is a cheap way of testing this with very little overhead. It does not + detect A->B->A linkages though for performance reason and the fact that it + takes a programming error for this to occur anyway. + + Authored with Benny Baumann (BenBE at geshi dot org). + + ok djm@ + + OpenBSD-Commit-ID: fb3fa9ee2cad3c7e842ebadfd7f5db220c4aaf16 + +commit fc48ddf6998188517af42dce807e2088b6a0c0be +Author: tobias@openbsd.org +Date: Wed Aug 14 15:37:11 2024 +0000 - upstream: %C is a callable macro in mdoc(7) + upstream: Use freezero for better readability + + It has the same meaning as the current pair of calling explicit_bzero + and free. Spotted with Benny Baumann (BenBE at geshi dot org). - so, as we do for %D, escape it; + ok djm@ - OpenBSD-Commit-ID: 538cfcddbbb59dc3a8739604319491dcb8e0c0c9 + OpenBSD-Commit-ID: 939fbe9ccf52d0d48c5fa53694d6f3bb9927970c -commit e0f91aa9c2fbfc951e9ced7e1305455fc614d3f2 -Author: djm@openbsd.org -Date: Fri Jul 28 05:33:15 2023 +0000 +commit 1ff6907ec26dac6ac59fe9fe232899a63b4c14d8 +Author: tobias@openbsd.org +Date: Wed Aug 14 15:35:23 2024 +0000 - upstream: don't need to start a command here; use ssh -N instead. + upstream: Fix typo in comment + + Spotted with Benny Baumann (BenBE at geshi dot org). - Fixes failure on cygwin spotted by Darren + ok djm@ - OpenBSD-Regress-ID: ff678a8cc69160a3b862733d935ec4a383f93cfb + OpenBSD-Commit-ID: 829160ac8ef3ad3409695ce3a3ade835061cae57 -commit f446a44f30bc680e0d026a4204844b02646c1c2d -Author: djm@openbsd.org -Date: Wed May 17 05:52:01 2023 +0000 +commit 487faaed8f3bb9ffb19e8f807a3da72895b16421 +Author: dlg@openbsd.org +Date: Wed Jul 31 12:00:18 2024 +0000 - upstream: add LTESTS_FROM variable to allow skipping of tests up to + upstream: add a random amount of time (up to 4 seconds) to the - a specific point. e.g. "make LTESTS_FROM=t-sftp" will only run the sftp.sh - test and subsequent ones. ok dtucker@ + grace login time. - OpenBSD-Regress-ID: 07f653de731def074b29293db946042706fcead3 - -commit 8eb8899d612440a9b608bee7f916081d3d0b7812 -Author: djm@openbsd.org -Date: Fri May 12 06:37:42 2023 +0000 - - upstream: test ChrootDirectory in Match block + ok deraadt@ djm@ - OpenBSD-Regress-ID: a6150262f39065939f025e546af2a346ffe674c1 + OpenBSD-Commit-ID: abd3c57aaa5861517529b322df79b6be35ee67f4 -commit e43f43d3f19516222e9a143468ea0dc1b3ab67b6 -Author: djm@openbsd.org -Date: Fri May 12 06:36:27 2023 +0000 +commit 2865f5b7520bed3e74fbbb5f8d7a44193d7a4314 +Author: naddy@openbsd.org +Date: Fri Jul 26 15:24:49 2024 +0000 - upstream: better error messages + upstream: document the reduced logingrace penalty - OpenBSD-Regress-ID: 55e4186604e80259496d841e690ea2090981bc7a + OpenBSD-Commit-ID: 9b63e0e3599d524ddc10edc4f978081382c3548b -commit 6958f00acf3b9e0b3730f7287e69996bcf3ceda4 -Author: djm@openbsd.org -Date: Thu Jul 27 22:26:49 2023 +0000 +commit 1ec0a64c5dc57b8a2053a93b5ef0d02ff8598e5c +Author: Darren Tucker +Date: Sun Jul 28 21:26:51 2024 +1000 - upstream: don't incorrectly truncate logged strings retrieved from - - PKCS#11 modules; based on GHPR406 by Jakub Jelen; ok markus + Explicitly install libssl-devel cygwin. - OpenBSD-Commit-ID: 7ed1082f23a13b38c373008f856fd301d50012f9 + Should fix CI tests for cygwin default config. -commit d1ffde6b55170cd4b9a72bfd9a3f17508e6cf714 +commit 0bf6e5bb750b66b25c20a1c5a471f91850de3748 Author: djm@openbsd.org -Date: Thu Jul 27 22:25:17 2023 +0000 +Date: Thu Jul 25 23:44:01 2024 +0000 - upstream: make sshd_config AuthorizedPrincipalsCommand and + upstream: reduce logingrace penalty. - AuthorizedKeysCommand accept the %D (routing domain) and a new %C (connection - address/port 4-tuple) as expansion sequences; ok markus + A single forgotton login that times out should be below the penalty + threshold. + + ok deraadt/claudio - OpenBSD-Commit-ID: ee9a48bf1a74c4ace71b69de69cfdaa2a7388565 + OpenBSD-Commit-ID: cee1f7d17597c97bff8e5092af5d136fdb08f81d -commit 999a2886ca1844a7a74b905e5f2c8c701f9838cd +commit 29fb6f6d46b67770084b4f12bcf8a01bd535041b Author: djm@openbsd.org -Date: Thu Jul 27 22:23:05 2023 +0000 +Date: Thu Jul 25 22:40:08 2024 +0000 - upstream: increase default KDF work-factor for OpenSSH format - - private keys from 16 to 24; { feedback ok } x { deraadt markus } + upstream: Fix proxy multiplexing (-O proxy) bug - OpenBSD-Commit-ID: a3afb1383f8ff0a49613d449f02395d9e8d4a9ec - -commit 0fa803a1dd1c7b546c166000e23a869cf6c4ec10 -Author: Darren Tucker -Date: Thu Jul 27 02:25:09 2023 +1000 - - Prefer OpenSSL's SHA256 in sk-dummy.so + If a mux started with ControlPersist then later has a forwarding added using + mux proxy connection and the forwarding was used, then when the mux proxy + session terminates, the mux master process will send a channel close to the + server with a bad channel ID and crash the connection. - Previously sk-dummy.so used libc's (or compat's) SHA256 since it may be - built without OpenSSL. In many cases, however, including both libc's - and OpenSSL's headers together caused conflicting definitions. + This was caused by my stupidly reusing c->remote_id for mux channel + associations when I should have just added another member to struct channel. - We tried working around this (on OpenSSL <1.1 you could define - OPENSSL_NO_SHA, NetBSD had USE_LIBC_SHA2, various #define hacks) with - varying levels of success. Since OpenSSL >=1.1 removed OPENSSL_NO_SHA - and including most OpenSSL headers would bring sha.h in, even if it - wasn't used directly this was a constant hassle. + ok markus@ - Admit defeat and use OpenSSL's SHA256 unless we aren't using OpenSSL at - all. ok djm@ - -commit 36cdb5dbf55c99c0faad06066f56a7c341258c1f -Author: Darren Tucker -Date: Thu Jul 27 10:29:44 2023 +1000 - - Retire dfly58 test VM. Add dfly64. + OpenBSD-Commit-ID: c9f474e0124e3fe456c5e43749b97d75e65b82b2 -commit 2d34205dab08ede9b0676efa57647fc49e6decbe +commit 53d1d307438517805989c7d5616d752739a97e03 Author: djm@openbsd.org -Date: Wed Jul 26 23:06:00 2023 +0000 - - upstream: make ssh -f (fork after authentication) work properly in - - multiplexed cases (inc. ControlPersist). bz3589 bz3589 Based on patches by - Peter Chubb; ok dtucker@ - - OpenBSD-Commit-ID: a7a2976a54b93e6767dc846b85647e6ec26969ac - -commit 076aeda86a7ee9be8fd2f0181ec7b9729a6ceb37 -Author: naddy@openbsd.org -Date: Sun Jul 23 20:04:45 2023 +0000 +Date: Thu Jul 18 01:47:27 2024 +0000 - upstream: man page typos; ok jmc@ + upstream: mention mux proxy mode - OpenBSD-Commit-ID: e6ddfef94b0eb867ad88abe07cedc8ed581c07f0 + OpenBSD-Commit-ID: fd77a77779f06d316a314e4540dc57c93fc3369a -commit 135e7d5fe31f700e6dfc61ce914970c5ee7175ba -Author: jmc@openbsd.org -Date: Thu Jul 20 05:43:39 2023 +0000 +commit a9b90859d252c2f5a24142f985d38610ac74685f +Author: jsg@openbsd.org +Date: Sun Jul 14 10:19:23 2024 +0000 - upstream: tweak the allow-remote-pkcs11 text; + upstream: fix double word; ok dtucker@ - OpenBSD-Commit-ID: bc965460a89edf76865b7279b45cf9cbdebd558a + OpenBSD-Commit-ID: e6aff005914fa350b896d2be030be3d3b56ec0e8 -commit 5f83342b61d1f76c141de608ed2bd293990416bd +commit b05fda224bbcd2f641254534ed2175c42487f3c8 Author: Darren Tucker -Date: Tue Jul 25 13:00:22 2023 +1000 +Date: Thu Jul 25 17:59:35 2024 +1000 - Handle a couple more OpenSSL no-ecc cases. + Check for SA_RESTART before using it. ok djm@ -commit edc2ef4e418e514c99701451fae4428ec04ce538 -Author: Damien Miller -Date: Thu Jul 20 12:53:44 2023 +1000 - - depend - -commit 51fda734e0d3c2df256fc03e8b060c4305be6e59 -Author: Damien Miller -Date: Thu Jul 20 12:53:21 2023 +1000 - - Bring back OPENSSL_HAS_ECC to ssh-pkcs11-client - -commit 099cdf59ce1e72f55d421c8445bf6321b3004755 -Author: djm@openbsd.org -Date: Wed Jul 19 14:03:45 2023 +0000 +commit c276672fc0e99f0c4389988d54a84c203ce325b6 +Author: Yuichiro Naito +Date: Wed Sep 1 10:19:32 2021 +0900 - upstream: Separate ssh-pkcs11-helpers for each p11 module - - Make ssh-pkcs11-client start an independent helper for each provider, - providing better isolation between modules and reliability if a single - module misbehaves. + Class-imposed login restrictions - This also implements reference counting of PKCS#11-hosted keys, - allowing ssh-pkcs11-helper subprocesses to be automatically reaped - when no remaining keys reference them. This fixes some bugs we have - that make PKCS11 keys unusable after they have been deleted, e.g. - https://bugzilla.mindrot.org/show_bug.cgi?id=3125 + If the following functions are available, + add an additional check if users are allowed to login imposed by login class. - ok markus@ + * auth_hostok(3) + * auth_timeok(3) - OpenBSD-Commit-ID: 0ce188b14fe271ab0568f4500070d96c5657244e + These functions are implemented on FreeBSD. -commit 29ef8a04866ca14688d5b7fed7b8b9deab851f77 +commit 7717b9e9155209916cc6b4b4b54f4e8fa578e889 Author: djm@openbsd.org -Date: Wed Jul 19 14:02:27 2023 +0000 +Date: Wed Jul 10 21:58:34 2024 +0000 - upstream: Ensure FIDO/PKCS11 libraries contain expected symbols - - This checks via nlist(3) that candidate provider libraries contain one - of the symbols that we will require prior to dlopen(), which can cause - a number of side effects, including execution of constructors. - - Feedback deraadt; ok markus + upstream: correct keyword; from Yatao Su via GHPR509 - OpenBSD-Commit-ID: 1508a5fbd74e329e69a55b56c453c292029aefbe + OpenBSD-Commit-ID: 81c778c76dea7ef407603caa157eb0c381c52ad2 -commit 1f2731f5d7a8f8a8385c6031667ed29072c0d92a +commit f2b78bb8f149d6b4d1f62c21aa1f06995dccf4ce Author: djm@openbsd.org -Date: Wed Jul 19 13:56:33 2023 +0000 +Date: Mon Jul 8 03:04:34 2024 +0000 - upstream: Disallow remote addition of FIDO/PKCS11 provider - - libraries to ssh-agent by default. - - The old behaviour of allowing remote clients from loading providers - can be restored using `ssh-agent -O allow-remote-pkcs11`. - - Detection of local/remote clients requires a ssh(1) that supports - the `session-bind@openssh.com` extension. Forwarding access to a - ssh-agent socket using non-OpenSSH tools may circumvent this control. - - ok markus@ + upstream: don't need return at end of void function - OpenBSD-Commit-ID: 4c2bdf79b214ae7e60cc8c39a45501344fa7bd7c + OpenBSD-Commit-ID: 42d322d37f13aa075ae7b1ad9eef591e20b89717 -commit 892506b13654301f69f9545f48213fc210e5c5cc +commit a395d37a813c0177cb5bfc4bebf5a52badb73cf0 Author: djm@openbsd.org -Date: Wed Jul 19 13:55:53 2023 +0000 +Date: Thu Jul 4 22:53:59 2024 +0000 - upstream: terminate process if requested to load a PKCS#11 provider + upstream: fix grammar: "a pattern lists" -> "one or more pattern - that isn't a PKCS#11 provider; from / ok markus@ + lists" - OpenBSD-Commit-ID: 39532cf18b115881bb4cfaee32084497aadfa05c - -commit f3f56df8ec476b2de6cbdbdfdb77a2a61087829d -Author: Damien Miller -Date: Wed Jul 19 12:07:18 2023 +1000 - - agent_fuzz doesn't want stdint.h conditionalised + OpenBSD-Commit-ID: f3c844763398faa9800687e8ff6621225498202a -commit 750911fd31d307a767cc86e3bfa90bbbb77b1a25 -Author: Damien Miller -Date: Tue Jul 18 15:41:12 2023 +1000 +commit 8b664df75966e5aed8dabea00b8838303d3488b8 +Author: Darren Tucker +Date: Sun Jul 7 18:46:19 2024 +1000 - conditionalise stdint.h inclusion on HAVE_STDINT_H + Cast to sockaddr * in systemd interface. - fixes build on AIX5 at least + Fixes build with musl libx. bz#3707. -commit ff047504fa6e008c4092f8929881816b8993bea0 -Author: Damien Miller -Date: Tue Jul 18 15:30:45 2023 +1000 +commit 30c8c81da2169e78357d08dbb0ddd823b60e93bc +Author: Darren Tucker +Date: Thu Jul 4 20:12:26 2024 +1000 - conditionalise match localnetwork on ifaddrs.h - - Fixes build breakage on platforms that lack getifaddrs() + Add 9.8 branch to ci-status page. -commit b87b03282e466ca2927954ce93f5dbf0bfdc68f6 -Author: djm@openbsd.org -Date: Mon Jul 17 06:16:33 2023 +0000 +commit ee6b9e661633fcefd29dba0c811cecbc4d027f6f +Author: Samuel Thibault +Date: Tue Mar 26 22:15:08 2024 +0100 - upstream: missing match localnetwork negation check + Fix detection of setres*id on GNU/Hurd - OpenBSD-Commit-ID: 9a08ed8dae27d3f38cf280f1b28d4e0ff41a737a + Like Linux, proper _SOURCE macros need to be set to get declarations of + various standard functions, notably setres*id. Now that Debian is using + -Werror=implicit-function-declaration this is really required. While at + it, define other _SOURCE macros like on GNU/Linux, since GNU/Hurd uses + the same glibc. -commit 6d6e185ba29ef4274164b77eab4dc763907f8821 -Author: jmc@openbsd.org -Date: Mon Jul 17 05:41:53 2023 +0000 +commit fa41f6592ff1b6ead4a652ac75af31eabb05b912 +Author: Damien Miller +Date: Mon Jul 1 14:33:26 2024 +1000 - upstream: - add -P to usage() - sync the arg name to -J in usage() - - with that in ssh.1 - reformat usage() to match what "man ssh" does on 80width - - OpenBSD-Commit-ID: 5235dd7aa42e5bf90ae54579d519f92fc107036e + version numbers -commit f1a9898283a0638667b587ee4a950afd61ab51b0 -Author: jmc@openbsd.org -Date: Mon Jul 17 05:38:10 2023 +0000 +commit bfebb8a5130a792c5356bd06e1ddef72a0a0449f +Author: djm@openbsd.org +Date: Mon Jul 1 04:31:59 2024 +0000 - upstream: -P before -p in SYNOPSIS; + upstream: openssh-9.8 - OpenBSD-Commit-ID: 535f5257c779e26c6a662a038d241b017f8cab7c + OpenBSD-Commit-ID: 5f8b89e38a4c5f7c6d52ffa19f796d49f36fab19 -commit eef4d7e873568e1c84c36bb4034e2c3378250a61 -Author: jsg@openbsd.org -Date: Mon Jul 17 05:36:14 2023 +0000 +commit 146c420d29d055cc75c8606327a1cf8439fe3a08 +Author: djm@openbsd.org +Date: Mon Jul 1 04:31:17 2024 +0000 - upstream: configuation -> configuration + upstream: when sending ObscureKeystrokeTiming chaff packets, we + + can't rely on channel_did_enqueue to tell that there is data to send. This + flag indicates that the channels code enqueued a packet on _this_ ppoll() + iteration, not that data was enqueued in _any_ ppoll() iteration in the + timeslice. ok markus@ - OpenBSD-Commit-ID: 4776ced33b780f1db0b2902faec99312f26a726b + OpenBSD-Commit-ID: 009b74fd2769b36b5284a0188ade182f00564136 -commit dc1dbe94cf6532bd546a3373ad436404f8850e5f +commit 637e4dfea4ed81264e264b6200172ce319c64ead Author: djm@openbsd.org -Date: Mon Jul 17 05:26:38 2023 +0000 +Date: Mon Jul 1 03:10:19 2024 +0000 - upstream: move other RCSIDs to before their respective license blocks + upstream: use "lcd" to change directory before "lls" rather then "cd", - too no code change + since the directory we're trying to list is local. Spotted by Corinna + Vinschen - OpenBSD-Commit-ID: ef5bf46b57726e4260a63b032b0b5ac3b4fe9cd4 + OpenBSD-Regress-ID: 821feca4a4bebe491944e624c8f7f2990b891415 -commit ebe11044681caff78834ca6b78311ad19c1860b8 +commit c8cfe258cee0b8466ea84597bf15e1fcff3bc328 Author: djm@openbsd.org -Date: Mon Jul 17 05:22:30 2023 +0000 +Date: Thu Jun 27 23:01:15 2024 +0000 - upstream: Move RCSID to before license block and away from #includes, - - where it caused merge conflict in -portable for each commit :( + upstream: delete obsolete comment - OpenBSD-Commit-ID: 756ebac963df3245258b962e88150ebab9d5fc20 + OpenBSD-Commit-ID: 5fb04f298ed155053f3fbfdf0c6fe7cdf84bbfa2 -commit 05c08e5f628de3ecf6f7ea20947735bcfa3201e0 +commit 94b9d37100f6fa536aaa1d1a0e4926fe44fbf04d Author: djm@openbsd.org -Date: Mon Jul 17 05:20:15 2023 +0000 +Date: Thu Jun 27 22:36:44 2024 +0000 - upstream: return SSH_ERR_KRL_BAD_MAGIC when a KRL doesn't contain a - - valid magic number and not SSH_ERR_MESSAGE_INCOMPLETE; the former is needed - to fall back to text revocation lists in some cases; fixes t-cert-hostkey. + upstream: retire unused API - OpenBSD-Commit-ID: 5c670a6c0f027e99b7774ef29f18ba088549c7e1 + OpenBSD-Commit-ID: 3e30d7b0615e2707f6bbe70f61b1c2f72f78161b -commit c6fad2c3d19b74f0bd0af1ef040fc74f3a1d9ebb -Author: Damien Miller -Date: Mon Jul 17 14:56:14 2023 +1000 +commit 268c3a7f5783e731ed60f4e28da66ee3743581d3 +Author: jmc@openbsd.org +Date: Thu Jun 27 21:02:16 2024 +0000 - avoid AF_LINK on platforms that don't define it + upstream: ssl(8) no longer contains a HISTORY section; + + OpenBSD-Commit-ID: 83b7ff34433d79595e9c2a5d2a561a6660251245 -commit 919bc3d3b712c920de1ae6be5ac6561c98886d7e +commit 12b6cc09ce6c430681f03af2a8069e37a664690b Author: djm@openbsd.org -Date: Mon Jul 17 04:08:31 2023 +0000 +Date: Wed Jun 26 23:47:46 2024 +0000 - upstream: Add support for configuration tags to ssh(1). - - This adds a ssh_config(5) "Tag" directive and corresponding - "Match tag" predicate that may be used to select blocks of - configuration similar to the pf.conf(5) keywords of the same - name. + upstream: move child process waitpid() loop out of SIGCHLD handler; - ok markus + ok deraadt - OpenBSD-Commit-ID: dc08358e70e702b59ac3e591827e5a96141b06a3 + OpenBSD-Commit-ID: 65815a39564e431414aed7c5ace8076f4e9ca741 -commit 3071d85a47061c1bdaf11a0ac233b501ecba862c -Author: djm@openbsd.org -Date: Mon Jul 17 04:04:36 2023 +0000 +commit d6bcd13297c2ab8b528df5a6898f994734849031 +Author: deraadt@openbsd.org +Date: Wed Jun 26 23:16:52 2024 +0000 - upstream: add a "match localnetwork" predicate. - - This allows matching on the addresses of available network interfaces - and may be used to vary the effective client configuration based on - network location (e.g. to use a ProxyJump when not on a particular - network). + upstream: Instead of using possibly complex ssh_signal(), write all - ok markus@ + the parts of the grace_alarm_handler() using the exact things allowed by the + signal-safe rules. This is a good rule of thumb: Handlers should be written + to either set a global volatile sig_atomic_t inspected from outside, and/or + directly perform only safe operations listed in our sigaction(2) manual page. + ok djm markus - OpenBSD-Commit-ID: cffb6ff9a3803abfc52b5cad0aa190c5e424c139 + OpenBSD-Commit-ID: 14168ae8368aab76e4ed79e17a667cb46f404ecd -commit beec17bb311365b75a0a5941418d4b96df7d7888 -Author: djm@openbsd.org -Date: Mon Jul 17 04:01:10 2023 +0000 +commit b8793e2b0851f7d71b97554fa5260b23796d6277 +Author: deraadt@openbsd.org +Date: Wed Jun 26 23:14:14 2024 +0000 - upstream: remove vestigal support for KRL signatures - - When the KRL format was originally defined, it included support for - signing of KRL objects. However, the code to sign KRLs and verify KRL - signatues was never completed in OpenSSH. - - Now, some years later, we have SSHSIG support in ssh-keygen that is - more general, well tested and actually works. So this removes the - semi-finished KRL signing/verification support from OpenSSH and - refactors the remaining code to realise the benefit - primarily, we - no longer need to perform multiple parsing passes over KRL objects. + upstream: save_errno wrappers inside two small signal handlers that - ok markus@ + perform system calls, for systems with libc that do perform libc sigtramps. + ok djm markus - OpenBSD-Commit-ID: 517437bab3d8180f695c775410c052340e038804 + OpenBSD-Commit-ID: 7749b56419a7c9dcfe4c6c04811e429813346c62 -commit 449566f64c21b4578d5c0c431badd0328adc53ed -Author: djm@openbsd.org -Date: Mon Jul 17 03:57:21 2023 +0000 +commit f23e9332c4c8df37465c4a4f38275ea98980ed7e +Author: jmc@openbsd.org +Date: Mon Jun 24 06:59:39 2024 +0000 - upstream: Support for KRL extensions. - - This defines wire formats for optional KRL extensions and implements - parsing of the new submessages. No actual extensions are supported at - this point. + upstream: - uppercase start of sentence - correct sentence grammar - ok markus + ok djm - OpenBSD-Commit-ID: ae2fcde9a22a9ba7f765bd4f36b3f5901d8c3fa7 + OpenBSD-Commit-ID: 1ec4b0fdb633a43667f2c8fff1d600bd647dde25 -commit 18ea857770e84825a3a6238bb37f54864487b59f -Author: dtucker@openbsd.org -Date: Fri Jul 14 07:44:21 2023 +0000 +commit 1839e3eb71a759aa795602c1e4196300f4ac2615 +Author: djm@openbsd.org +Date: Mon Jun 24 04:05:11 2024 +0000 - upstream: Include stdint.h for SIZE_MAX. Fixes OPENSSL=no build. + upstream: mention SshdSessionPath option - OpenBSD-Commit-ID: e7c31034a5434f2ead3579b13a7892960651e6b0 + OpenBSD-Commit-ID: c29734d36c21003973b15c1c9965c35f36cef30c -commit 20b768fcd13effe0f2d3619661b6c8592c773553 +commit 603193e32aef5db7d60c58066d5de89806e79312 Author: Darren Tucker -Date: Fri Jul 14 17:07:32 2023 +1000 - - Fix typo in declaration of nmesg. - -commit 4b94d09542e36ebde2eb9ad89bc68431609932de -Author: Damien Miller -Date: Fri Jul 14 15:34:47 2023 +1000 +Date: Thu Jun 20 18:45:14 2024 +1000 - portable-specific int overflow defence-in-depth - - These too are unreachable, but we want the code to be safe regardless of - context. Reported by Yair Mizrahi @ JFrog + Rerun upstream tests on .sh file changes too. -commit 2ee48adb9fc8692e8d6ac679dcc9f35e89ad68f0 -Author: djm@openbsd.org -Date: Fri Jul 14 05:31:44 2023 +0000 +commit dbbf9337c19381786a8e5a8a49152fe6b80c780d +Author: dtucker@openbsd.org +Date: Thu Jun 20 08:23:18 2024 +0000 - upstream: add defence-in-depth checks for some unreachable integer - - overflows reported by Yair Mizrahi @ JFrog; feedback/ok millert@ + upstream: Work around dbclient cipher/mac query bug. - OpenBSD-Commit-ID: 52af085f4e7ef9f9d8423d8c1840a6a88bda90bd - -commit 4b43bc358ae6f6b19a973679246dc5172f6ac41b -Author: djm@openbsd.org -Date: Mon Jul 10 04:51:26 2023 +0000 - - upstream: misplaced debug message + Unlike earlier versions, recent Dropbear (at least v2024.85) requires + a host arg when querying supported ciphers and macs via "-c/-m + help". Earlier versions accept but do not require it, so always + provide it. If these queries fail, skip the test with a warning. - OpenBSD-Commit-ID: d0f12af0a5067a756aa707bc39a83fa6f58bf7e5 + OpenBSD-Regress-ID: 98eb863a3f0363416922efb273885e6b3c7f68d4 -commit 8c7203bcee4c4f98a22487b4631fe068b992099b -Author: Damien Miller -Date: Wed Jul 12 11:41:19 2023 +1000 +commit 8de2c8cebc46bbdb94b7a2c120fcadfb66a3cccc +Author: dtucker@openbsd.org +Date: Thu Jun 20 08:18:34 2024 +0000 - replace deprecate selinux matchpathcon function + upstream: Remove dropbear key types not supported - This function is apparently deprecated. Documentation on what is the - supposed replacement is is non-existent, so this follows the approach - glibc used https://sourceware.org/git/?p=glibc.git;a=patch;h=f278835f59 + by current OpenSSH. Allows subsequent test runs to work if OpenSSH is + rebuilt w/out OpenSSL. - ok dtucker@ + OpenBSD-Regress-ID: e0129eb2b1d31771105903a8055216fbba20a770 -commit 7e8800f5d701efffa39ccb63ca1e095ea777c31a -Author: dtucker@openbsd.org -Date: Thu Jul 6 22:17:59 2023 +0000 +commit e9b6471c59b21e5d9ef1b3832d4bf727338add85 +Author: djm@openbsd.org +Date: Thu Jun 20 00:18:05 2024 +0000 - upstream: minleft and maxsign are u_int so cast appropriately. Prompted - - by github PR#410, ok deraadt. + upstream: stricter check for overfull tables in penalty record path - OpenBSD-Commit-ID: 0514cd51db3ec60239966622a0d3495b15406ddd + OpenBSD-Commit-ID: 7df01e648a0723418c554e64a9f2b6d38db060a6 -commit 94842bfe9b09fc93189c6ed0dc9bbebc1d44a426 -Author: dlg@openbsd.org -Date: Tue Jul 4 03:59:21 2023 +0000 +commit d9336d344eb2a1e898c5e66147b3f108c7214694 +Author: djm@openbsd.org +Date: Wed Jun 19 23:24:47 2024 +0000 - upstream: add support for unix domain sockets to ssh -W + upstream: put back reaping of preauth child process when writes - ok djm@ dtucker@ + from the monitor fail. Not sure how this got lost in the avalanche of + patches. - OpenBSD-Commit-ID: 3e6d47567b895c7c28855c7bd614e106c987a6d8 + OpenBSD-Commit-ID: eb7eb36371e1ac01050b32b70fb2b3e5d98e72f5 -commit a95fc5eed09a0238fb127b6c50e8498432b79dae -Author: David Seifert -Date: Fri May 12 14:06:01 2023 +0200 +commit 579d9adb70ec0206a788eb5c63804c31a67e9310 +Author: naddy@openbsd.org +Date: Mon Jun 17 13:50:18 2024 +0000 - gss-serv.c: `MAXHOSTNAMELEN` -> `HOST_NAME_MAX` - - `MAXHOSTNAMELEN` is not defined in POSIX, which breaks on musl: - https://pubs.opengroup.org/onlinepubs/9699919799/functions/gethostname.html + upstream: remove one more mention of DSA - Bug: https://bugs.gentoo.org/834044 + OpenBSD-Commit-ID: 8515f55a15f02836ba657df341415f63c60526ca -commit 8a6cd08850f576e7527c52a1b086cae82fab290e +commit 7089b5f8436ef0b8d3d3ad9ce01045fb9e7aab15 Author: Darren Tucker -Date: Fri Jun 23 09:49:02 2023 +1000 - - Update runner OS version for hardenedmalloc test. - - Hardenedmalloc dropped support for "legacy glibc" versions in their - 64dad0a69 so use a newer Ubuntu version for the runner for that test. - -commit cfca6f17e64baed6822bb927ed9f372ce64d9c5b -Author: Damien Miller -Date: Thu Jun 22 15:04:03 2023 +1000 +Date: Wed Jun 19 23:09:05 2024 +1000 - handle sysconf(SC_OPEN_MAX) returning > INT_MAX; - - bz3581; ok dtucker + Move -f to the place needed to restart sshd. -commit c1c2ca1365b3f7b626683690bd2c68265f6d8ffd -Author: djm@openbsd.org -Date: Wed Jun 21 05:10:26 2023 +0000 +commit d5f83cfd852b14a25f347f082ab539a9454702ad +Author: Darren Tucker +Date: Wed Jun 19 21:04:01 2024 +1000 - upstream: better validate CASignatureAlgorithms in ssh_config and - - sshd_config. - - Previously this directive would accept certificate algorithm names, but - these were unusable in practice as OpenSSH does not support CA chains. - - part of bz3577; ok dtucker@ - - OpenBSD-Commit-ID: a992d410c8a78ec982701bc3f91043dbdb359912 + Need to supply "-f" to restart sshd. -commit 4e73cd0f4ab3e5b576c56cac9732da62c8fc0565 -Author: djm@openbsd.org -Date: Wed Jun 21 05:08:32 2023 +0000 +commit fad34b4ca25c0ef31e5aa841d461b6f21da5b8c1 +Author: dtucker@openbsd.org +Date: Wed Jun 19 10:15:51 2024 +0000 - upstream: make `ssh -Q CASignatureAlgorithms` only list signature + upstream: Provide defaults for ciphers and macs - algorithms that are valid for CA signing. Previous behaviour was to list all - signing algorithms, including certificate algorithms (OpenSSH certificates do - not support CA chains). part of bz3577; ok dtucker@ + if querying for them fails since on some versions of Dropbear (at least + v2024.85) "-m help" doesn't seem to work. Enable all supported pubkey + algorithms in the server. - OpenBSD-Commit-ID: 99c2b072dbac0f44fd1f2269e3ff6c1b5d7d3e59 + OpenBSD-Regress-ID: 4f95556a49ee9f621789f25217c367a33d2745ca -commit a69062f1695ac9c3c3dea29d3044c72aaa6af0ea -Author: djm@openbsd.org -Date: Wed Jun 21 05:06:04 2023 +0000 +commit 5521060e35ada9f957cecdddc06d0524e75409ef +Author: dtucker@openbsd.org +Date: Wed Jun 19 10:10:46 2024 +0000 - upstream: handle rlimits > INT_MAX (rlim_t is u64); ok dtucker + upstream: Use ed25519 keys for kex tests - bz3581 + since that's supported by OpenSSH even when built without OpenSSL. + Only test diffie-hellman kex if OpenSSH is compiled with support for it. - OpenBSD-Commit-ID: 31cf59c041becc0e5ccb0a77106f812c4cd1cd74 + OpenBSD-Regress-ID: a5d09ef9bbd171f9e4ec73ed0d9eeb49a8878e97 -commit 8d33f2aa6bb895a7f85a47189913639086347b75 -Author: djm@openbsd.org -Date: Tue Jun 20 23:59:33 2023 +0000 +commit dbd3b833f6e3815e58f2dc6e14f61a51bcd4d6bd +Author: dtucker@openbsd.org +Date: Wed Jun 19 10:08:34 2024 +0000 - upstream: prepare for support for connecting to unix domain sockets + upstream: Rework dropbear key setup - using ssh -W by explicitly decoding PORT_STREAMLOCAL (a negative number) from - the u32 that's passed over the multiplexing socket; previously code would - just cast, which is UB. + to always generate ed25519 keys, other types only if OpenSSH has support + for the corresponding key type. - OpenBSD-Commit-ID: e5ac5f40d354096c51e8c118a5c1b2d2b7a31384 + OpenBSD-Regress-ID: 8f91f12604cddb9f8d93aa34f3f93a3f6074395d -commit b4ac435b4e67f8eb5932d8f59eb5b3cf7dc38df0 -Author: djm@openbsd.org -Date: Tue Jun 20 00:05:09 2023 +0000 +commit d6218504e11ae9148adf410fc69b0710a052be36 +Author: Darren Tucker +Date: Wed Jun 19 20:20:24 2024 +1000 - upstream: reset comment=NULL for each key in do_fingerprint(); - - fixes "no comment" not showing on when running `ssh-keygen -l` on multiple - keys where one has a comment and other following keys do not. Patch from - Markus Kuhn via GHPR407, bz3580 + Restart sshd after installing it for testing. - OpenBSD-Commit-ID: 3cce84456fdcd67dc6b84e369f92c6686d111d9b + When installing an sshd built without OpenSSL the mismatch between + the running sshd and newly installed sshd-session will cause the + remainder of the test to fail. -commit b53a809a549dcd4fbde554c6aa283e597b15ea33 -Author: millert@openbsd.org -Date: Mon Jun 5 13:24:36 2023 +0000 +commit 786a4465b6bb702daf4fb17b7c3bcb42b52f0b46 +Author: Darren Tucker +Date: Tue Jun 18 19:59:59 2024 +1000 - upstream: Store timeouts as int, not u_int as they are limited to - - INT_MAX. Fixes sign compare warnings systems with 32-bit time_t due to type - promotion. OK djm@ + Remove macos-11 runner. - OpenBSD-Commit-ID: 48081e9ad35705c5f1705711704a4c2ff94e87b7 + Github is retiring them soon. -commit 2709809fd616a0991dc18e3a58dea10fb383c3f0 -Author: Philip Hands -Date: Wed May 24 19:41:14 2023 +0200 +commit df1c72a55edbebac14363b57de66ac6a147ecc67 +Author: Damien Miller +Date: Wed Jun 19 09:34:34 2024 +1000 - fixup! if -s & -p specified, mention 'sftp -P' on - - success - - SSH-Copy-ID-Upstream: 32686e7c65b4fa2846e474d3315102dfa0f043b0 + PAMServiceName may appear in a Match block -commit 204e0bf05161b7641500d7ab266c21217412379f -Author: Darren Tucker -Date: Tue Aug 3 21:25:48 2021 +1000 +commit de1c2e70e5a5dc3c8d2fe04b24cc93d8ef6930e7 +Author: dtucker@openbsd.org +Date: Tue Jun 18 08:11:48 2024 +0000 - Make ssh-copy-id(1) consistent with OpenSSH. - - This makes the ssh-copy-id man page more consistent with the rest of the - OpenSSH man pages: - - new sentence, new line - - no sentences >80 - - N.B. -> NB - - zap unused .Pp - - zap trailing whitespace + upstream: Re-enable ssh-dss tests - Report from Debian via mindrot bz#3331, diff from jmc at openbsd.org. + ... if ssh is compiled with DSA support - SSH-Copy-ID-Upstream: d8974cfb6242316460ed22a1ccc662800a50c5d3 + OpenBSD-Regress-ID: bbfaf8c17f2b50a2d46ac35cb97af99b990c990d -commit 9de79df66d1430d290fab670bb4b18612875e518 -Author: Philip Hands -Date: Wed May 24 11:45:43 2023 +0200 +commit dabc2c7cf3c141e8e5d5a1a60d6c1d2d2422cf43 +Author: anton@openbsd.org +Date: Tue Jun 18 06:14:27 2024 +0000 - if -s & -p specified, mention 'sftp -P' on success - - This was inspired by this: - https://github.com/openssh/openssh-portable/pull/321 - but I thought that it was better to not do the sed patching. - - BTW the reason one can get away with using $SSH_OPTS throughout, despite - the lowercase -p in there, even if sftp is in use, is that the sftp call - is using the already-established ssh master connection, so the port was - passed to the earlier ssh. + upstream: Stop using DSA in dropbear interop tests. - SSH-Copy-ID-Upstream: 1c124d9bfafdbe28a00b683367ebf5750ce12eb2 + OpenBSD-Regress-ID: abfd4457d99d8cc1417fd22ca2c570270f74c1cf -commit 801cda54c00e0f4e7d89345a90874c8d05dc233a -Author: Philip Hands -Date: Tue May 23 23:07:11 2023 +0200 +commit 761438012710169445acc179e3870c53c862bda0 +Author: Damien Miller +Date: Tue Jun 18 12:29:45 2024 +1000 - drop whitespace - - SSH-Copy-ID-Upstream: e604fae1cdee35c18055d35dcec530cf12ef00ad + missed a bit of DSA in the fuzzer -commit 288482f53613f3e74544eb92deeb24f7c7f1f371 -Author: Philip Hands -Date: Tue May 23 20:52:13 2023 +0200 +commit 3f9cc47da588e8de520720e59f98438043fdaf93 +Author: Damien Miller +Date: Tue Jun 18 09:35:53 2024 +1000 - make -x also apply to the target script - - SSH-Copy-ID-Upstream: 3c4214704f427bd0654adf9b0fc079253db21cf4 + DSA support is disabled, so remove from fuzzers -commit b79e7b88ed44f0e4339f0ff35c96c78a92175a8d -Author: Philip Hands -Date: Tue May 23 16:46:42 2023 +0200 +commit 00eb95957dea5484b2c7c043f7d2bbc87301bef2 +Author: djm@openbsd.org +Date: Mon Jun 17 08:30:29 2024 +0000 - add -t option to specify the target path - - Allow the default target path (.ssh/authorized_files) to be over-riden + upstream: disable the DSA signature algorithm by default; ok - This was inspired by this MR from Panagiotis Cheilaris + markus@ - https://gitlab.com/phil_hands/ssh-copy-id/-/merge_requests/8 + (yes, I know this expands to "the Digitial Signature Algorithm + signature algorithm) - SSH-Copy-ID-Upstream: a942a0e076874adb6d8b2f0fb76d6c7918190fcd + OpenBSD-Commit-ID: 961ef594e46dd2dcade8dd5721fa565cee79ffed -commit 914f4ad138714c471ba72fb6d5496b6235320edd -Author: Carlos Rodríguez Gili -Date: Tue Apr 20 19:23:57 2021 +0200 +commit 5603befe11c9464ea26fe77cbacc95a7cc0b1ea7 +Author: djm@openbsd.org +Date: Mon Jun 17 08:28:31 2024 +0000 - Fix test error for /bin/sh on Solaris 10 and older + upstream: promote connection-closed messages from verbose to info - On Solaris 10 and older targets /bin/sh is not POSIX-compliant. - Test -z `...` fails with error 'sh: test: argument expected'. - Using quotes around backticks fixes this and doesn't break - POSIX compatibility. + log level; they could be the only record of the connection terminating if the + client doesn't send a SSH2_MSG_DISCONNECT message. ok dtucker@ - SSH-Copy-ID-Upstream: 98394072a3f985b2650c1e8eab2fef84e38cc065 + OpenBSD-Commit-ID: 0c8bfaf5e9fdff945cee09ac21e641f6c5d65d3c -commit bd382dca316c721aed1e45edcf4c4e0f6374afb0 -Author: Jakub Jelen -Date: Tue Mar 2 21:34:05 2021 +0000 +commit b00331402fe5c60d577f3ffcc35e49286cdc6b47 +Author: Damien Miller +Date: Mon Jun 17 17:02:18 2024 +1000 - Remove outdated comment - - The commit b068122 removed the code dropping the trailing colon, but the comment stayed leaving the code confusing for future readers + propagate PAM crashes to PerSourcePenalties - SSH-Copy-ID-Upstream: 930d39f238117cd53810240ec989d0356aa1c1f6 + If the PAM subprocess crashes, exit with a crash status that will be + picked up by the sshd(8) listener process where it can be used by + PerSourcePenalties to block the client. This is similar handling to + the privsep preauth process. -commit bdcaf7939029433635d63aade8f9ac762aca2bbe -Author: Darren Tucker -Date: Wed May 10 18:50:46 2023 +1000 +commit 1c207f456ace38987deda047758d13fbf857f948 +Author: Damien Miller +Date: Mon Jun 17 15:06:01 2024 +1000 - Special case OpenWrt instead of Dropbear. - - OpenWrt overrides the location of authorized_keys for root. Currently we - assume that all Dropbear installations behave this way, which is not the - case. Check for OpenWrt and root user before using that location instead - of assuming that for all Dropbear servers. Prompted by Github PR#250. + minix doesn't have loopback, so skip penalty tests - SSH-Copy-ID-Upstream: 0e1f5d443a9967483c33945793107ae3f3e4af2d + pointed out by dtucker@ -commit cf84498f67abe93f813a296167b406a0db7b288e -Author: Philip Hands -Date: Thu May 18 18:20:55 2023 +0200 +commit 48443d202eaec52d4d39defdd709a4499a7140c6 +Author: djm@openbsd.org +Date: Sun Jun 16 11:54:49 2024 +0000 - ssh-copy-id: add -x option (for debugging) - - This option causes the ssh-copy-id to run with set -x + upstream: same treatment for this test - SSH-Copy-ID-Upstream: a0ee367ea8c0a29c8b4515245e408d2d349e7844 + OpenBSD-Regress-ID: d0cc9efca7833e673ea7b0cb3a679a3acee8d4c7 -commit b4a1efdcb88f03394c08e7f68ed4e11676830002 -Author: Philip Hands -Date: Thu May 18 17:14:41 2023 +0200 +commit 45562a95ea11d328c22d97bf39401cd29684fb1f +Author: djm@openbsd.org +Date: Sun Jun 16 08:18:06 2024 +0000 - update copyright notices + upstream: penalty test is still a bit racy - SSH-Copy-ID-Upstream: c284ed33b361814ea48ff68cbd01ca525b2bf117 + OpenBSD-Regress-ID: 90c9ac224db454637baf1ebee5857e007321e824 -commit fcd78e31cdd45a7e69ccfe6d8a3b1037dc1de290 +commit 8d0f7eb147ef72d18acb16c0b18672d44941a8ca Author: djm@openbsd.org -Date: Wed May 24 23:01:06 2023 +0000 +Date: Sat Jun 15 03:59:10 2024 +0000 - upstream: fix AuthorizedPrincipalsCommand when AuthorizedKeysCommand + upstream: crank up penalty timeouts so this should work on even the - appears previously in configuration. Reported by John Meyers in bz3574 ok - dtucker@ + slowest of test builders - OpenBSD-Commit-ID: 1c92e4517284386703936e1d3abaa36cfacf1951 + OpenBSD-Regress-ID: 70bda39c83e3fc9d0f3c1fad4542ed33e173d468 -commit 5ec5504f1d328d5bfa64280cd617c3efec4f78f3 -Author: dtucker@openbsd.org -Date: Wed May 10 10:04:20 2023 +0000 +commit 93c75471a1202ab3e29db6938648d4e2602c0475 +Author: jmc@openbsd.org +Date: Fri Jun 14 05:20:34 2024 +0000 - upstream: Remove unused prototypes for ssh1 RSA functions. - - From lengyijun via github PR#396. + upstream: sort -q in the options list; - OpenBSD-Commit-ID: 379a5afa8b7a0f3cba0c8a9bcceb4e5e33a5c1ef - -commit fbf362b3891ae4b36052d1b39f37fc618b41c476 -Author: Darren Tucker -Date: Tue May 9 19:26:56 2023 +1000 - - main(void) to prevent unused variable warning. - -commit baf854c8bb0a6d0af5c696c801e631a48dabbaba -Author: Darren Tucker -Date: Tue May 9 19:25:45 2023 +1000 - - Remove warning pragma since clang doesn't like it. - -commit 5fbb7a1349fbbb48ccb1b8cafff2c1854370d87d -Author: Darren Tucker -Date: Tue May 9 17:13:33 2023 +1000 - - Suppress warning for snprintf truncation test. - -commit 47742c513e4e045ecc985c6483fc5c8b050acda2 -Author: Darren Tucker -Date: Tue May 9 17:12:50 2023 +1000 - - Update OpenSSL compat test for 3.x. - -commit 86ad25d455a2313126125540e61e0f9314283f88 -Author: Darren Tucker -Date: Mon May 8 20:23:08 2023 +1000 - - Add macos13 PAM test target. + OpenBSD-Commit-ID: 6839b38378f38f754de638a5e988c13b4164cc7c -commit 77cca2c4b13bc6e5f389565583b6202b0d1bccc2 -Author: Darren Tucker -Date: Mon May 8 20:14:46 2023 +1000 +commit dd7807bbe80a93ffb4616f2bd5cf83ad5a5595fb +Author: djm@openbsd.org +Date: Fri Jun 14 05:01:22 2024 +0000 - Skip agent-peereid test on macos13. + upstream: clarify KEXAlgorithms supported vs available. Inspired by - sudo -S nobody doesn't work on the github runners (probably a - permission issue) so skip that test. - -commit b356b8e91678ea295bcf44df5248c3fbf499fdcf -Author: Darren Tucker -Date: Mon May 8 20:14:28 2023 +1000 - - Include config.guess in debug output. - -commit b7afd8a4ecaca8afd3179b55e9db79c0ff210237 -Author: Darren Tucker -Date: Mon May 8 20:12:59 2023 +1000 - - Handle OpenSSL >=3 ABI compatibility. + bz3701 from Colin Watson. - Beyond OpenSSL 3.0, the ABI compatibility guarantees are wider (only - major must match instead of major and minor in earlier versions). - bz#3548, ok djm@ + OpenBSD-Commit-ID: e698e69bea19bd52971d253f2b1094490c4701f7 -commit 0e9e2663eb2c6e9c3e10d15d70418312ae67e542 -Author: dtucker@openbsd.org -Date: Mon May 1 08:57:29 2023 +0000 +commit d172ad56df85b68316dbadbedad16761a1265874 +Author: djm@openbsd.org +Date: Fri Jun 14 05:00:42 2024 +0000 - upstream: Import regenerated moduli. + upstream: ssh-keyscan -q man bits - OpenBSD-Commit-ID: 3d5f811cfcaed8cc4a97e1db49ac61bdf118113c + OpenBSD-Commit-ID: ba28d0e1ac609a4c99c453e57e86560c79079db1 -commit d9687f49682e1e93383fc15ab2018850b2ef38c3 -Author: Darren Tucker -Date: Mon May 1 11:45:14 2023 +1000 +commit 092e4ff9ccaacbe035f286feb1b56ed499604743 +Author: Damien Miller +Date: Fri Jun 14 14:46:35 2024 +1000 - Add macos-13 test target. - - Also flatten OS list for clarity. + skip penalty-expire test in valgrind test env -commit aacfd6767497b8fa6d41ecdd3f8e265d1e9ef1f6 +commit 2866ad08a9c50d7b67ce9424ca990532b806a21a Author: djm@openbsd.org -Date: Sun Apr 30 22:54:22 2023 +0000 +Date: Fri Jun 14 04:43:11 2024 +0000 - upstream: adjust ftruncate() logic to handle servers that reorder - - requests. - - sftp/scp will ftruncate the destination file after a transfer completes, - to deal with the case where a longer destination file already existed. - We tracked the highest contiguous block transferred to deal with this - case, but our naive tracking doesn't deal with servers that reorder - requests - a misfeature strictly permitted by the protocol but seldom - implemented. + upstream: split the PerSourcePenalties test in two: one tests penalty - Adjust the logic to ftruncate() at the highest absolute block received - when the transfer is successful. feedback deraadt@ ok markus@ + enforcement but not penalty expiry, the other tests penalty expiry. - prompted by https://github.com/openssh/openssh-portable/commit/9b733#commitcomment-110679778 + This lets us disable the expiry testing in certain CI test environments. - OpenBSD-Commit-ID: 4af7fac75958ad8507b4fea58706f3ff0cfddb1b + OpenBSD-Regress-ID: f56811064f3e3cb52ee73a206b8c2a06af1c8791 -commit c8eb3941758615c8284a48fff47872db926da63c -Author: djm@openbsd.org -Date: Wed Apr 26 01:36:03 2023 +0000 +commit b2c64bc170d75823622a37cab3ca1804ca87ad16 +Author: Damien Miller +Date: Fri Jun 14 14:19:23 2024 +1000 - upstream: Check for ProxyJump=none in CanonicalizeHostname logic. - - Previously ssh would incorrectly refuse to canonicalise the hostname - if ProxyJump was explicitly set to "none" when CanonicalizeHostname=yes + add a sshd_config PamServiceName option - bz3567; ok dtucker + Allows selecting which PAM service name to use when UsePAM is + enabled. Defaults to "sshd" unless overridden at compile time + by defining SSHD_PAM_SERVICE. - OpenBSD-Commit-ID: 80a58e43c3a32f97361282f756ec8d3f37989efd + bz2102, ok dtucker@ -commit ac383f3a5c6f529a2e8a5bc44af79a08c7da294e -Author: jsg@openbsd.org -Date: Wed Apr 12 14:22:04 2023 +0000 +commit 9f032a4dd17bf0ae6066223d82aa5e784285d987 +Author: djm@openbsd.org +Date: Fri Jun 14 00:26:12 2024 +0000 - upstream: remove duplicate signal.h include + upstream: don't redirect stderr for ssh-keyscan we expect to succeed - OpenBSD-Commit-ID: 30c0a34d74d91ddd0e6992525da70d3293392f70 + OpenBSD-Regress-ID: 8878b8eb4e070ed2e343166d3eb86db4a08a216c -commit 740dafa20f3f3d325f6f5d44e990b8c8a6d3d816 -Author: jsg@openbsd.org -Date: Wed Apr 12 08:53:54 2023 +0000 +commit 1e84d0cf40e94ae3a77d6a7ca8c036d8e3d55a40 +Author: djm@openbsd.org +Date: Fri Jun 14 00:25:25 2024 +0000 - upstream: fix double words ok dtucker@ + upstream: make host/banner comments go to stderr instead of stdout, - OpenBSD-Commit-ID: 44d3223902fbce5276422bdc8063ab72a4078489 - -commit 6452f89577ec4f22440c31b8e19b061d1a7c4b2a -Author: Darren Tucker -Date: Tue Apr 11 16:49:19 2023 +1000 - - Test against LibreSSL 3.7.2. + so they are useful as comments without extra shell redirection and so they + don't clutter actual errors on stderr. + + Add a -q flag to shut them up. + + ok dtucker@ + + OpenBSD-Commit-ID: bec813de56a71adb5c1a76adcf49621130d24264 -commit 2138f6be595ca106fe4805a1e3ab9c4d8acc697b -Author: Damien Miller -Date: Thu Apr 6 14:33:10 2023 +1000 +commit 3e806d011855d6bd648ec95b9df630ebbd11c3bf +Author: naddy@openbsd.org +Date: Thu Jun 13 15:06:33 2024 +0000 - remove unused upper-case const strings in fmtfp + upstream: separate keywords with comma - no float format that uses upper-case is supported nor are hex floats. - ok dtucker + OpenBSD-Commit-ID: d65a99666202a8188c4991c18d14374a229f7be5 -commit 484c5e6168fdb22cbcd73c4ff987cf9ca47989ca +commit abfd1f7a3cbd0a92581a0febba254b2f6649c0d9 Author: djm@openbsd.org -Date: Thu Apr 6 03:56:02 2023 +0000 +Date: Fri Jun 14 00:23:55 2024 +0000 - upstream: simplify sshsig_find_principals() similar to what happened to + upstream: specify an algorithm for ssh-keyscan, otherwise it will make - sshsig_check_allowed_keys() in r1.31, removing some dead code + multiple attempts simultaneously and confuse the test - OpenBSD-Commit-ID: a493e628d4d6c08f878c276d998f4313ba61702d + OpenBSD-Regress-ID: 6e910f3315c4345053db1bf5cbf61826b194d0b9 -commit 3a7b110fbc7e096423f8f7b459deffe4c65d70f4 -Author: djm@openbsd.org -Date: Thu Apr 6 03:21:31 2023 +0000 +commit a8fbe2f7d0d96d299ee8e69769e3b51067978748 +Author: Damien Miller +Date: Thu Jun 13 16:41:29 2024 +1000 - upstream: remove redundant ssh!=NULL check; we'd already + sshd: don't use argv[0] as PAM service name + + sshd would implicitly use argv[0] as the PAM service name to + allow people to select different PAM service names by making + differently-named copies/links to the sshd binary. - dereferenced it + Splitting sshd into sshd/sshd-session broke this, as the process + that starts PAM is always sshd-session and the user has no control + over this. - OpenBSD-Commit-ID: 852bf12591ec5a9fb12dcbde9b1fd3945ad0df3c + Hardcode "sshd" as the default PAM service name unless/until we + figure out a better way. Should unbreak OSX integration tests. -commit 2519110659a1efac6c976895a86659d1b341c91b -Author: djm@openbsd.org -Date: Thu Apr 6 03:19:32 2023 +0000 +commit bf204bd05c3ae650f87e2b96527688579f59774c +Author: Damien Miller +Date: Thu Jun 13 15:00:28 2024 +1000 - upstream: match_user() shouldn't be called with user==NULL unless - - host and ipaddr are also NULL + prepare for checking in autogenerated files - OpenBSD-Commit-ID: fa3518346c21483e9e01a2e4b9436ae501daf8ea + We plan to check in automatically generated files (config.h.in, etc) on + release branches. These files are normally ignored by .gitignore, but + this shuffles the contents of this file to make it easy to un-ignore + them. -commit 3b9ceaad7ad63c1c03c2a89e148340ad3a62a482 -Author: djm@openbsd.org -Date: Thu Apr 6 03:12:32 2023 +0000 +commit 425f79a837489904c343b349ef00e09aeaa4e752 +Author: Damien Miller +Date: Thu Jun 13 14:41:33 2024 +1000 - upstream: don't care about glob() return value here. - - OpenBSD-Commit-ID: 85bb82fea90478a482e9f65a1bec0aa24227fd66 + typo in comment -commit 09d8da0849e2791b2500267cda333cd238f38754 -Author: dtucker@openbsd.org -Date: Mon Apr 3 08:10:54 2023 +0000 +commit afe10313c1fa8d478af399ee7d54c8f85503013b +Author: Damien Miller +Date: Thu Jun 13 14:35:25 2024 +1000 - upstream: Move up null check and simplify process_escapes. + fix PTY allocation on Cygwin, broken by sshd split - Based on Coverity CID 291863 which points out we check the channel - pointer for NULLness after dereferencing it. Move this to the start - of the function, and while there simplify initialization of efc a bit. - ok djm@ + Cygwin doesn't support FD passing and so used to disable post-auth + privilege separation entirely because privsep requires PTY allocation + to happen in the privileged monitor process with the PTY file + descriptors being passed back to the unprivileged process. + + This brings back a minimal version of the previous special treatment + for Cygwin (and any other platform that sets DISABLE_FD_PASSING): + privilege separation remains enabled, but PTY allocation happens in + the post-auth user process rather than the monitor. + + This either requires PTY allocation to not need privilege to begin + with (this appears to be the case on Cygwin), or the post-auth + privsep process retain privilege (other platforms that set the + DISABLE_FD_PASSING option). - OpenBSD-Commit-ID: de36e5ad6fde0fe263ca134e986b9095dc59380a + Keeping privileges here is bad, but the non-Cygwin systems that set + DISABLE_FD_PASSING are so deeply legacy that this is likely to be the + least of their problems. -commit b36b162be5e6206f12b734222b7bc517c13a6bc8 +commit f66d4df5749551380a8c4ae642347675a0b6a2e9 Author: Damien Miller -Date: Fri Mar 31 14:51:20 2023 +1100 +Date: Thu Jun 13 11:33:09 2024 +1000 - need va_end() after va_copy(); ok dtucker + delay lookup of privsep user until config loaded - spotted by Coverity + sshd-session attempting to use options.kerberos_authentication to + decide whether it needed to lookup the privsep user before the + configuration was loaded. This caused it to get a placeholder value + that caused it always to try to lookup the privsep user, breaking at + least one test environment. -commit f703757234a5c585553e72bba279b255a272750a -Author: dtucker@openbsd.org -Date: Fri Mar 31 05:56:36 2023 +0000 +commit f1c42858b94f5d9b58867b34dce3afb39c6b56a8 +Author: Damien Miller +Date: Thu Jun 13 11:16:57 2024 +1000 - upstream: Explicitly ignore return from waitpid here too. - - OpenBSD-Commit-ID: eef2403df083c61028969fc679ee370373eacacb + missing file for PerSourcePenalties regress test -commit 6b73aa29035991d1448a1a76f63ac152a6bf931c -Author: dtucker@openbsd.org -Date: Fri Mar 31 04:45:08 2023 +0000 +commit 4de80ff4e6fab5a6bb0028e7d57c6c23d1485adb +Author: djm@openbsd.org +Date: Wed Jun 12 22:36:00 2024 +0000 - upstream: Explictly ignore return codes + upstream: split PerSourcePenalties address tracking. Previously it - where we don't check them. + used one shared table and overflow policy for IPv4 and IPv6 addresses, now it + will use separate tables and optionally different overflow policies. - OpenBSD-Commit-ID: 1ffb03038ba1b6b72667be50cf5e5e396b5f2740 - -commit 6f0308a3e717ebe68eeb3f95253612fab5dbf20e -Author: dtucker@openbsd.org -Date: Fri Mar 31 04:42:29 2023 +0000 - - upstream: Return immediately from get_sock_port + This prevents misbehaviour from IPv6 addresses (which are vastly easier + to obtain many of) from affecting IPv4 connections and may allow for + stricter overflow policies. - if sock <0 so we don't call getsockname on a negative FD. From Coverity - CID 291840, ok djm@ + ok deraadt@ - OpenBSD-Commit-ID: de1c1130646230c2eda559831fc6bfd1b61d9618 + OpenBSD-Commit-ID: 12637ed0aa4d5f1f3e702da42ea967cbd8bfdfd9 -commit 1c1124dc901fca1ea2cb762044b8f1a5793a2bed -Author: djm@openbsd.org -Date: Fri Mar 31 04:23:02 2023 +0000 +commit 06ab4c6931b0aaa4334db2faaa7e1069e76d0df6 +Author: jmc@openbsd.org +Date: Tue Jun 11 05:24:39 2024 +0000 - upstream: don't leak arg2 on parse_pubkey_algos error path; ok - - dtucker@ + upstream: do not mark up "(default: 20ms)"; - OpenBSD-Commit-ID: 7d0270ad3dd102412ca76add2b3760518abdef75 + OpenBSD-Commit-ID: 54151ecdecfa1b67dcdda4fd24826ef6e2148ad4 -commit 8ba2d4764bb6a4701cd447d8b52604622ffe65f4 +commit cfe243cd9fde148ed060637876e27bb55ac78be9 Author: djm@openbsd.org -Date: Fri Mar 31 04:22:27 2023 +0000 +Date: Tue Jun 11 02:54:51 2024 +0000 - upstream: clamp max number of GSSAPI mechanisms to 2048; ok dtucker + upstream: reap preauth net child if it hangs up during privsep message - OpenBSD-Commit-ID: ce66db603a913d3dd57063e330cb5494d70722c4 + send, not just message receive + + OpenBSD-Commit-ID: 02a093f4ab4f8f83f0cd1ea2bb35b9ca420448f0 -commit 1883841fc13d0eada8743cac5d3abe142ee2efa7 +commit b0a711c00b9c64afd1c9d6fb538275c6604a2676 Author: djm@openbsd.org -Date: Fri Mar 31 04:21:56 2023 +0000 +Date: Tue Jun 11 01:58:27 2024 +0000 - upstream: don't print key if printing hostname failed; with/ok + upstream: fix PIDFILE handling, broken for SUDO=doas in last commit - dtucker@ + here - OpenBSD-Commit-ID: ad42971a6ee5a46feab2d79f7f656f8cf4b119f3 + OpenBSD-Regress-ID: 96fec579af228f87a036e94801eb294af9074625 -commit c6011129cafe4c411f6ef670a4cf271314708eb8 +commit 90fb801e2d9241be50a2a7ff79428386442a041f Author: djm@openbsd.org -Date: Fri Mar 31 04:04:15 2023 +0000 +Date: Tue Jun 11 02:00:30 2024 +0000 - upstream: remove redundant test + upstream: reap the pre-auth [net] child if it hangs up during privsep - OpenBSD-Commit-ID: 6a0b719f9b1ae9d42ad8c5b144c7962c93792f7c + message sending, not just receiving + + OpenBSD-Commit-ID: f7341605bf08c4c15830910446e6775323f2f8cb -commit 4fb29eeafb40a2076c0dbe54e46b687c318f87aa +commit ef878d58798f6688c7f4d4e417dc0c29023ea831 Author: djm@openbsd.org -Date: Fri Mar 31 04:00:37 2023 +0000 +Date: Tue Jun 11 01:23:25 2024 +0000 - upstream: don't attempt to decode a ridiculous number of - - attributes; harmless because of bounds elsewhere, but better to be explicit + upstream: a little more RB_TREE paranoia - OpenBSD-Commit-ID: 1a34f4b6896155b80327d15dc7ccf294b538a9f2 + OpenBSD-Commit-ID: 8dc2fd21eebd8830c4a4d25461ac4fe228e11156 -commit fc437c154ef724621a4af236de9bc7e51a8381ae +commit fc4e96b2174d6a894d2033421699d091679baced Author: djm@openbsd.org -Date: Fri Mar 31 03:22:49 2023 +0000 +Date: Tue Jun 11 01:22:25 2024 +0000 - upstream: remove unused variable; prompted by Coverity CID 291879 + upstream: fix off-by-one comparison for PerSourcePenalty - OpenBSD-Commit-ID: 4c7d20ef776887b0ba1aabcfc1b14690e4ad0a40 + OpenBSD-Commit-ID: af4f5d01c41ef870b23e55655bfbf73474a6c02b -commit 0eb8131e4a53b33a8fc9b9ab694e6b6778b87ade -Author: dtucker@openbsd.org -Date: Fri Mar 31 00:44:29 2023 +0000 +commit 82c836df4ff41145553cd7adb11c5b985aeaa06f +Author: djm@openbsd.org +Date: Tue Jun 11 01:21:41 2024 +0000 - upstream: Check fd against >=0 instead of >0 in error path. The - - dup could in theory return fd 0 although currently it doesn't in practice. - From Dmitry Belyavskiy vi github PR#238. + upstream: move tree init before possible early return - OpenBSD-Commit-ID: 4a95f3f7330394dffee5c749d52713cbf3b54846 + OpenBSD-Commit-ID: 72e2c5b69f151c08a7c5bf5ad929b97a92c273df -commit 7174ba6f8a431ca4257767a260fc50e204068242 -Author: dtucker@openbsd.org -Date: Thu Mar 30 07:19:50 2023 +0000 +commit a2300f015cc4939c4d9c564b58b74e71202dc978 +Author: djm@openbsd.org +Date: Tue Jun 11 01:07:35 2024 +0000 - upstream: Ignore return value from muxclient(). It normally loops - - without returning, but it if returns on failure we immediately exit. - Coverity CID 405050. + upstream: update to mention that PerSourcePenalties default to - OpenBSD-Commit-ID: ab3fde6da384ea588226037c38635a6b2e015295 - -commit a4c1c2513e36f111eeaa1322c510067930e5e51e -Author: Damien Miller -Date: Fri Mar 31 14:17:22 2023 +1100 - - don't call connect() on negative socket + being enabled and document the default values for each parameter. - Coverity CID 405037 + OpenBSD-Commit-ID: b981288bddfb097aad269f62df4081c688ce0034 -commit 34ee842cdd981a759fe8f0d4a37521f9a1c63170 +commit 41987efd356d3fc30139aeab4b09374acf8f91a0 Author: djm@openbsd.org -Date: Thu Mar 30 03:05:01 2023 +0000 +Date: Tue Jun 11 00:44:52 2024 +0000 - upstream: return SSH_ERR_KEY_NOT_FOUND if the allowed_signers file + upstream: reap the [net] child if it hangs up while writing privsep - is empty, not SSH_ERR_INTERNAL_ERROR. Also remove some dead code spotted - by Coverity; with/ok dtucker@ + message payloads, not just the message header - OpenBSD-Commit-ID: 898a1e817cda9869554b1f586a434f67bcc3b650 + OpenBSD-Commit-ID: 24dbd400aa381ac96be7ed2dd49018487dfef6ce -commit f108e77a9dc9852e72215af1bf27731c48434557 -Author: dtucker@openbsd.org -Date: Thu Mar 30 00:49:37 2023 +0000 +commit 6211aa085fa91155a24922e5329576ac9a8f3175 +Author: djm@openbsd.org +Date: Tue Jun 11 00:40:21 2024 +0000 - upstream: Remove dead code from inside if block. - - The only way the if statement can be true is if both dup()s fail, and - in that case the tmp2 can never be set. Coverity CID 291805, ok djm@ + upstream: log waitpid() status for abnormal exits - OpenBSD-Commit-ID: c0d6089b3fb725015462040cd94e23237449f0c8 + OpenBSD-Commit-ID: b317930e06b51819c1a2bc6a4359764fecfb1c2d -commit 05b8e88ebe23db690abbfb1a91111abea09cde08 -Author: Darren Tucker -Date: Thu Mar 30 13:53:29 2023 +1100 +commit a59634c7adb9ae988748d99963dfafb3070d8d41 +Author: djm@openbsd.org +Date: Tue Jun 11 00:36:20 2024 +0000 - child_set_eng: verify both env pointer and count. + upstream: correct error message - If child_set env was called with a NULL env pointer and a non-zero count - it would end up in a null deref, although we don't currently do this. - Prompted by Coverity CID 291850, tweak & ok djm@ + OpenBSD-Commit-ID: 581f60f73099083392887206860229ab104620ed -commit 28f1b8ef9b84b8cd2f6c9889a0c60aa4a90dadfa -Author: dtucker@openbsd.org -Date: Wed Mar 29 01:07:48 2023 +0000 +commit fa7d7a667f2ee031e72873e36de2d2a36bca973b +Author: deraadt@openbsd.org +Date: Fri Jun 7 13:23:30 2024 +0000 - upstream: Ignore return from sshpkt_disconnect + upstream: avoid shadowing issues which some compilers won't accept - since we set our own return value for the function. Coverity CID 291797, - ok djm@ + ok djm - OpenBSD-Commit-ID: 710b57ba954c139240895e23feea41f203201f04 + OpenBSD-Commit-ID: 1e89572397dda83433d58c4fa6333a08f51170d4 -commit c3da05d95922f5550bcc7815e799474d6a160175 -Author: dtucker@openbsd.org -Date: Wed Mar 29 00:59:08 2023 +0000 +commit 3ad4cd9eeca5c9bc6706db44b6de88e2e4513fd6 +Author: jmc@openbsd.org +Date: Thu Jun 6 21:14:49 2024 +0000 - upstream: Plug potential mem leak in process_put. + upstream: escape the final dot at eol in "e.g." to avoid double - It allocates abs_dst inside a loop but only frees it on exit, so free - inside the loop if necessary. Coverity CID 291837, ok djm@ + spacing; - OpenBSD-Commit-ID: a01616503a185519b16f00dde25d34ceaf4ae1a3 + OpenBSD-Commit-ID: 0a9fb10bc9f7d577afe2da3f498a08bc431115b9 -commit 13ae327eae598b1043e5ec30e4b170edb3c898a5 +commit 0e0c69761a4c33ccd4a256560f522784a753d1a8 Author: djm@openbsd.org -Date: Wed Mar 29 00:18:35 2023 +0000 +Date: Thu Jun 6 20:25:48 2024 +0000 - upstream: fix memory leak; Coverity CID 291848 + upstream: enable PerSourcePenalties by default. - with/ok dtucker@ + ok markus - OpenBSD-Commit-ID: 37f80cb5d075ead5a00ad1b74175684ab1156ff8 - -commit 9ffa76e1284c85bf459c3dcb8e995733a8967e1b -Author: dtucker@openbsd.org -Date: Tue Mar 28 07:44:32 2023 +0000 - - upstream: Plug more mem leaks in sftp by making + NB. if you run a sshd that accepts connections from behind large NAT + blocks, proxies or anything else that aggregates many possible users + behind few IP addresses, then this change may cause legitimate traffic + to be denied. - make_absolute_pwd_glob work in the same way as make_absolute: you - pass it a dynamically allocated string and it either returns it, or - frees it and allocates a new one. Patch from emaste at freebsd.org and - https://reviews.freebsd.org/D37253 ok djm@ + Please read the PerSourcePenalties, PerSourcePenaltyExemptList and + PerSourceNetBlockSize options in sshd_config(5) for how to tune your + sshd(8) for your specific circumstances. - OpenBSD-Commit-ID: 85f7404e9d47fd28b222fbc412678f3361d2dffc + OpenBSD-Commit-ID: 24a0e5c23d37e5a63e16d2c6da3920a51078f6ce -commit 82b2b8326962b1a98af279bc5bbbbbcab15b3e45 -Author: dtucker@openbsd.org -Date: Tue Mar 28 06:12:38 2023 +0000 +commit bd1f74741daabeaf20939a85cd8cec08c76d0bec +Author: djm@openbsd.org +Date: Thu Jun 6 20:20:42 2024 +0000 - upstream: Remove compat code for OpenSSL < 1.1.* + upstream: mention that PerSourcePenalties don't affect concurrent - since -portable no longer supports them. + in-progress connections. - OpenBSD-Commit-ID: ea2893783331947cd29a67612b4e56f818f185ff + OpenBSD-Commit-ID: 20389da6264f2c97ac3463edfaa1182c212d420c -commit b500afcf00ae1b6b73b2ccf171111dfbfeaef74d -Author: dtucker@openbsd.org -Date: Mon Mar 27 23:56:54 2023 +0000 +commit 9774b938578327d88a651f4c63c504809717590a +Author: djm@openbsd.org +Date: Thu Jun 6 19:49:25 2024 +0000 - upstream: Remove compat code for OpenSSL 1.0.* - - versions now that -portable has dropped support for those versions. + upstream: regress test for PerSourcePenalties - OpenBSD-Regress-ID: 82a8eacd87aec28e4aa19f17246ddde9d5ce7fe7 + OpenBSD-Regress-ID: a1af13d411b25a727742644459d26480b9a1b0f1 -commit 727560e6011efcb36d2f3ac6910444bc775abaa1 -Author: Darren Tucker -Date: Tue Mar 28 18:06:42 2023 +1100 +commit b8ebd86cefe9812204a10c028dc90de29918667d +Author: djm@openbsd.org +Date: Thu Jun 6 19:48:40 2024 +0000 - Prevent conflicts between Solaris SHA2 and OpenSSL. + upstream: make sure logs are saved from sshd run via start_sshd - We used to prevent conflicts between native SHA2 headers and OpenSSL's - by setting OPENSSL_NO_SHA but that was removed prior to OpenSSL 1.1.0 + OpenBSD-Regress-ID: de4ef0e32e3ab85ff3a6c36eb08d1909c0dd1b4a -commit 46db8e14b7f186d32173dcdecd5b785334429b8b -Author: Darren Tucker -Date: Tue Mar 28 12:44:03 2023 +1100 +commit d7b2070bdaa4ebbfafb9975c1d5a62b73289d31f +Author: djm@openbsd.org +Date: Thu Jun 6 19:47:48 2024 +0000 - Remove HEADER_SHA_H from previous... + upstream: simplify - since it causes more problems than it solves. + OpenBSD-Regress-ID: 50316e0d1ae0c0a057a45af042253e54ce23d11c -commit 72bd68d37387aa5f81da928f6e82f1c88ed8f674 -Author: Darren Tucker -Date: Tue Mar 28 10:35:18 2023 +1100 +commit e6ea3d224513b6bfb93818809d4c7397f5995ba2 +Author: djm@openbsd.org +Date: Thu Jun 6 18:48:13 2024 +0000 - Replace OPENSSL_NO_SHA with HEADER_SHA_H. + upstream: prepare for PerSourcePenalties being enabled by default - Since this test doesn't use OpenSSL's SHA2 and may cause conflicts we - don't want to include it, but OPENSSL_NO_SHA was removed beginning in - OpenSSL's 1.1 series. - -commit 99668f2e6e0deb833e46cfab56db59ff0fc28c7e -Author: Darren Tucker -Date: Tue Mar 28 09:50:06 2023 +1100 - - Configure with --target instead of deprecated form. - -commit f751d9306c62cd1061f966e6a7483d9bab9c379b -Author: Darren Tucker -Date: Mon Mar 27 22:05:29 2023 +1100 - - Pass rpath when building 64bit Solaris. - -commit a64b935cd450ee8d04c26c9cd728629cf9ca5c91 -Author: Darren Tucker -Date: Mon Mar 27 19:21:19 2023 +1100 - - Explicitly disable OpenSSL on AIX test VM. - -commit 7ebc6f060fc2f70495a56e16d210baae6424cd96 -Author: dtucker@openbsd.org -Date: Mon Mar 27 03:56:50 2023 +0000 - - upstream: Add RevokedHostKeys to percent expansion test. + in future - OpenBSD-Regress-ID: c077fd12a38005dd53d878c5b944154dec88d2ff + OpenBSD-Regress-ID: 5236c6d1c823997aac5a35e2915da30f1903bec7 -commit f1a17de150f8d309d0c52f9abfaebf11c51a8537 -Author: dtucker@openbsd.org -Date: Mon Mar 27 03:56:11 2023 +0000 +commit c0cb3b8c837761816a60a3cdb54062668df09652 +Author: djm@openbsd.org +Date: Thu Jun 6 19:50:01 2024 +0000 - upstream: Add tilde and environment variable expansion to - - RevokedHostKeys. bz#3552, ok djm@ + upstream: disable stderr redirection before closing fds - OpenBSD-Commit-ID: ce5d8e0219b63cded594c17d4c2958c06918ec0d + OpenBSD-Commit-ID: d42cb895ee4542098050367fc35321c9303f003a -commit 009eb4cb48a9708ab9174684dcbcc0f942907abe +commit 81c1099d22b81ebfd20a334ce986c4f753b0db29 Author: djm@openbsd.org -Date: Mon Mar 27 03:31:05 2023 +0000 +Date: Thu Jun 6 17:15:25 2024 +0000 - upstream: fix test: getnameinfo returns a non-zero value on error, not + upstream: Add a facility to sshd(8) to penalise particular - (neccessarily) -1. From GHPR#384 + problematic client behaviours, controlled by two new sshd_config(5) options: + PerSourcePenalties and PerSourcePenaltyExemptList. - OpenBSD-Commit-ID: d35e2b71268f66f5543a7ea68751972b3ae22b25 - -commit 4f0a676486700f10a4788f7e9426e94e39c1c89e -Author: djm@openbsd.org -Date: Mon Mar 27 03:25:08 2023 +0000 - - upstream: scp: when copying local->remote, check that source file + When PerSourcePenalties are enabled, sshd(8) will monitor the exit + status of its child pre-auth session processes. Through the exit + status, it can observe situations where the session did not + authenticate as expected. These conditions include when the client + repeatedly attempted authentication unsucessfully (possibly indicating + an attack against one or more accounts, e.g. password guessing), or + when client behaviour caused sshd to crash (possibly indicating + attempts to exploit sshd). - exists before opening SFTP connection to the server. Based on GHPR#370 ok - dtucker, markus + When such a condition is observed, sshd will record a penalty of some + duration (e.g. 30 seconds) against the client's address. If this time + is above a minimum threshold specified by the PerSourcePenalties, then + connections from the client address will be refused (along with any + others in the same PerSourceNetBlockSize CIDR range). - OpenBSD-Commit-ID: b4dd68e15bfe22ce4fac9960a1066a2b721e54fb - -commit 154d8baf631327163571760c2c524bc93c37567c -Author: Darren Tucker -Date: Mon Mar 27 12:22:30 2023 +1100 - - Also look for gdb error message from OpenIndiana. - -commit fbd3811ddb2b6ce2e6dba91fde7352c8978e5412 -Author: Darren Tucker -Date: Mon Mar 27 11:08:00 2023 +1100 - - Explicitly disable security key test on aix51 VM. + Repeated offenses by the same client address will accrue greater + penalties, up to a configurable maximum. A PerSourcePenaltyExemptList + option allows certain address ranges to be exempt from all penalties. - We don't know how to build the shared objects required for the security - key tests so skip them. - -commit 4922ac3be8a996780ef3dc220411da2e27c29d9c -Author: Darren Tucker -Date: Sun Mar 26 14:49:43 2023 +1100 - - Split libcrypto and other config flags. + We hope these options will make it significantly more difficult for + attackers to find accounts with weak/guessable passwords or exploit + bugs in sshd(8) itself. - This should allow the automatic OpenSSL version selection in the tests - to work better. - -commit 4a948b1469f185e871160a2d70e2a0fce2858f9e -Author: Darren Tucker -Date: Sun Mar 26 14:39:45 2023 +1100 - - Specify test target if we build without OpenSSL. + PerSourcePenalties is off by default, but we expect to enable it + automatically in the near future. - When we decide we can't use the versions of OpenSSL available, also - restrict the tests we run to avoid the ones that need OpenSSL. - -commit b308c636f5b5d89eecb98be00b3d56306a005a09 -Author: Darren Tucker -Date: Sun Mar 26 14:22:53 2023 +1100 - - Find suitable OpenSSL version. + much feedback markus@ and others, ok markus@ - Check the installed OpenSSL versions for a suitable one, and if there - isn't (and we don't have a specific version configured) then build - without OpenSSL. + OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca -commit 021ea5c2860f133f44790970968e0e73208b3a87 +commit 916b0b6174e203cf2c5ec9bcf409472eb7ffbf43 Author: Damien Miller -Date: Fri Mar 24 15:02:52 2023 +1100 +Date: Fri Jun 7 03:31:02 2024 +1000 - Github testing support for BoringSSL + whitespace -commit 9a97cd106466a2a9bda2bfaa4c48c4f1b2cc9c1b -Author: Damien Miller -Date: Fri Mar 24 15:34:29 2023 +1100 +commit 49b55e44182b8294419aa580cbf043d5b9e3d953 +Author: deraadt@openbsd.org +Date: Tue Jun 4 15:14:45 2024 +0000 - BoringSSL doesn't support EC_POINT_point2bn() + upstream: enable -fret-clean on amd64, for libc libcrypto ld.so - so don't invoke it in unittest - -commit cc5969c033a032d126ff78e5d95cf20abbede4c7 -Author: Damien Miller -Date: Fri Mar 24 15:34:05 2023 +1100 - - another ERR_load_CRYPTO_strings() vestige - -commit 4974293899a068133e976f81d6693670d2b576ca -Author: Damien Miller -Date: Fri Mar 24 15:24:05 2023 +1100 - - don't use obsolete ERR_load_CRYPTO_strings() + kernel, and all the ssh tools. The dynamic objects are entirely ret-clean, + static binaries will contain a blend of cleaning and non-cleaning callers. - OpenSSL (and elsewhere in OpenSSH) uses ERR_load_crypto_strings() + OpenBSD-Commit-ID: 112aacedd3b61cc5c34b1fa6d9fb759214179172 -commit 3c527d55f906e6970d17c4cab6db90ae9e013235 +commit cc80d51d034bcb24fd0f2564a4bdf1612000a2a2 Author: Damien Miller -Date: Fri Mar 24 15:23:05 2023 +1100 +Date: Wed Jun 5 02:21:30 2024 +1000 - Allow building with BoringSSL + remove PRIVSEP macros for osx -commit b7e27cfd7f163fc16b4c5d041cc28ee488a5eeec -Author: Damien Miller -Date: Fri Mar 24 15:21:18 2023 +1100 +commit 8785491123d4d722b310c20f383570be758f8263 +Author: djm@openbsd.org +Date: Sat Jun 1 07:03:37 2024 +0000 - put back SSLeay_version compat in configure test + upstream: be really strict with fds reserved for communication with the - Needed to detect old versions and give good "your version is bad" - messages at configure time; spotted by dtucker@ - -commit 7280401bdd77ca54be6867a154cc01e0d72612e0 -Author: Damien Miller -Date: Fri Mar 24 13:56:25 2023 +1100 - - remove support for old libcrypto + separate sshd-session process - reserve them early and fatal if we can't + dup2(2) them later. The pre-split fallback to re-reading the configuration + files is not possible, so sshd-session absolutely requires the fd the + configuration is passed over to be in order. - OpenSSH now requires LibreSSL 3.1.0 or greater or - OpenSSL 1.1.1 or greater + ok deraadt@ - with/ok dtucker@ - -commit abda22fb48302f2142233f71d27c74040288c518 -Author: Darren Tucker -Date: Sun Mar 19 15:36:13 2023 +1100 - - Test latest OpenSSL 1.1, 3.0 and LibreSSL 3.7. - -commit 610ac1cb077cd5a1ebfc21612154bfa13d2ec825 -Author: Darren Tucker -Date: Thu Mar 16 21:38:04 2023 +1100 - - Show 9.3 branch instead of 9.2. + OpenBSD-Commit-ID: 308a98ef3c8a6665ebf92c7c9a0fc9600ccd7065 -commit cb30fbdbee869f1ce11f06aa97e1cb8717a0b645 +commit f1c8918cb98459910fb159373baea053ba4108c0 Author: Damien Miller -Date: Thu Mar 16 08:28:19 2023 +1100 +Date: Fri May 31 19:12:26 2024 +1000 depend -commit 1dba63eb10c40b6fda9f5012ed6ae87e2d3d028e +commit 94b4866cb1f4b0ed29a9f367047b30f81002316f Author: Damien Miller -Date: Thu Mar 16 08:27:54 2023 +1100 - - crank version - -commit ba7532d0dac9aaf0ad7270664c43837fc9f64a5f -Author: djm@openbsd.org -Date: Wed Mar 15 21:19:57 2023 +0000 +Date: Fri May 31 19:11:14 2024 +1000 - upstream: openssh-9.3 + rename need_privsep to need_chroot - OpenBSD-Commit-ID: 8011495f2449c1029bb316bd015eab2e00509848 + privsep is mandatory, chroot is optional (disabled when running + sshd as non-root) -commit 6fd4daafb949b66bf555f3100f715a9ec64c3390 -Author: dtucker@openbsd.org -Date: Tue Mar 14 07:28:47 2023 +0000 +commit e68a95142e5024b144f8eeccd5ffdee42c34f44c +Author: Damien Miller +Date: Fri May 31 19:05:34 2024 +1000 - upstream: Free KRL ptr in addition to its contents. - - From Coverity CID 291841, ok djm@ - - OpenBSD-Commit-ID: f146ba08b1b43af4e0d7ad8c4dae3748b4fa31b6 + remove remaining use_privsep mention -commit 1d270bd303afaf6d94e9098cbbf18e5e539e2088 -Author: dtucker@openbsd.org -Date: Tue Mar 14 07:26:25 2023 +0000 +commit b21d271f651d2536dca819cc6d74032fe98634db +Author: djm@openbsd.org +Date: Fri May 31 09:01:08 2024 +0000 - upstream: Check pointer for NULL before deref. + upstream: warn when -r (deprecated option to disable re-exec) is - None of the existing callers seem to do that, but it's worth checking. - From Coverity CID 291834, ok djm@ + passed - OpenBSD-Commit-ID: a0a97113f192a7cb1a2c97b932f677f573cda7a4 + OpenBSD-Commit-ID: 73145ef5150edbe3ce7889f0844ed8fa6155f551 -commit d95af508e78c0cd3dce56b83853baaa59ae295cf -Author: dtucker@openbsd.org -Date: Sun Mar 12 10:40:39 2023 +0000 +commit a4b5bc246cbca476deeeb4462aa31746a56e3021 +Author: djm@openbsd.org +Date: Fri May 31 08:49:35 2024 +0000 - upstream: Limit number of entries in SSH2_MSG_EXT_INFO - - request. This is already constrained by the maximum SSH packet size but this - makes it explicit. Prompted by Coverity CID 291868, ok djm@ markus@ + upstream: typos - OpenBSD-Commit-ID: aea023819aa44a2dcb9dd0fbec10561896fc3a09 + OpenBSD-Commit-ID: edfa72eb06bfa65da30fabf7d2fe76d2d33f77bf -commit 8f287ba60d342b3e2f750e7332d2131e3ec7ecd0 -Author: dtucker@openbsd.org -Date: Sun Mar 12 09:41:18 2023 +0000 +commit 8054b906983ceaed01fabd8188d3dac24c05ba39 +Author: djm@openbsd.org +Date: Mon May 27 01:52:26 2024 +0000 - upstream: calloc can return NULL but xcalloc can't. - - From Coverity CID 291881, ok djm@ + upstream: don't need sys/queue.h here - OpenBSD-Commit-ID: 50204b755f66b2ec7ac3cfe379d07d85ca161d2b + OpenBSD-Commit-ID: dd137396828171eb19e4911581812ca58de6c578 -commit 83a56a49fd50f4acf900f934279482e4ef329715 -Author: dtucker@openbsd.org -Date: Fri Mar 10 07:17:08 2023 +0000 +commit 210d4239733da6180ce853538aeb9413d5c62ad5 +Author: naddy@openbsd.org +Date: Sun May 26 20:35:12 2024 +0000 - upstream: Explicitly ignore return from fcntl - - (... FD_CLOEXEC) here too. Coverity CID 291853. + upstream: remove references to SSH1 and DSA server keys - OpenBSD-Commit-ID: 99d8b3da9d0be1d07ca8dd8e98800a890349e9b5 + OpenBSD-Commit-ID: 57cc1c98d4f998981473734f144b904af7d178a2 -commit 0fda9d704d3bbf54a5e64ce02a6fecb11fe7f047 -Author: Damien Miller -Date: Fri Mar 10 15:59:46 2023 +1100 +commit f0b9261d7fdd0ef86806b49fe76344bd16770cd0 +Author: jsg@openbsd.org +Date: Thu May 23 23:47:16 2024 +0000 - bounds checking for getrrsetbyname() replacement; + upstream: remove unused struct fwd_perm_list, no decl with complete - Spotted by Coverity in CID 405033; ok millert@ - -commit 89b8df518f21677045599df0ad3e5dd0f39909b5 -Author: dtucker@openbsd.org -Date: Fri Mar 10 04:06:21 2023 +0000 - - upstream: Plug mem leak on error path. Coverity CID 405026, ok djm@. + type ok djm@ - OpenBSD-Commit-ID: 8212ca05d01966fb5e72205c592b2257708a2aac + OpenBSD-Commit-ID: 416fb3970b7e73c76d2963c4f00cf96f2b2ee2fb -commit bf4dae0ad192c3e2f03f7223834b00d88ace3d3e -Author: Darren Tucker -Date: Fri Mar 10 14:46:57 2023 +1100 +commit 2477a98c3ef78e63b11a1393656e00288f52ae97 +Author: naddy@openbsd.org +Date: Wed May 22 15:24:55 2024 +0000 - Add prototypes for mkstemp replacements. + upstream: Do not pass -Werror twice when building with clang. - Should prevent warnings due to our wrapper function. + OpenBSD-Commit-ID: 5f378c38ad8976d507786dc4db9283a879ec8cd0 -commit 4e04d68d6a33cdc73b831fd4b5e6124175555d3d -Author: dtucker@openbsd.org -Date: Fri Mar 10 03:01:51 2023 +0000 +commit 435844f5675245b4271f8581f15e6d1f34fde3bc +Author: miod@openbsd.org +Date: Wed May 22 11:49:36 2024 +0000 - upstream: Expliticly ignore return code from fcntl(.. FD_CLOEXEC) since + upstream: Do not pass -Werror if building with gcc 3, for asn1.h - there's not much we can do anyway. From Coverity CID 291857, ok djm@ + and bio.h cause (admittedly bogus) warnings with gcc 3. - OpenBSD-Commit-ID: 051429dd07af8db3fec10d82cdc78d90bb051729 + OpenBSD-Commit-ID: fb39324748824cb0387e9d67c41d1bef945c54ea -commit d6d38fd77cbe091c59e1bb720c3a494df4990640 +commit fc5dc092830de23767c6ef67baa18310a64ee533 Author: djm@openbsd.org -Date: Fri Mar 10 02:32:04 2023 +0000 +Date: Wed May 22 04:20:00 2024 +0000 - upstream: Like sshd_config, some ssh_config options are not + upstream: this test has been broken since 2014, and has been + + testing the same key exchange algorithm repeatedly instead of testing all of + them. Spotted by nreilly AT blackberry.com in bz3692 - first-match-wins. sshd_config.5 was fixed in r1.348, this is the same for - this file + Who broke the test? me. - OpenBSD-Commit-ID: 7be55b9351cde449b136afcc52d07aa4113b215e + OpenBSD-Regress-ID: 48f4f5946276f975667141957d25441b3c9a50e2 -commit 7187d3f86bf8f2066cc9941f217d23b0cacae25e -Author: dtucker@openbsd.org -Date: Fri Mar 10 02:24:56 2023 +0000 +commit fd4816791beaed2fdae7eea3e1494d1972b2a39d +Author: anton@openbsd.org +Date: Sun May 19 19:10:01 2024 +0000 - upstream: Remove no-op (int) > INT_MAX checks + upstream: Add missing kex-names.c source file required since the - since they can never be true. From Coverity CID 405031, ok djm@ + ssh split. - OpenBSD-Commit-ID: 9df3783b181e056595e2bb9edf7ed41d61cf8e84 + OpenBSD-Regress-ID: ca666223f828fc4b069cb9016bff1eb50faf9fbb -commit 77adde4305542ebe3005dd456122624fe2347b01 -Author: Darren Tucker -Date: Fri Mar 10 13:27:29 2023 +1100 +commit beccb7319c5449f6454889013403c336446d622e +Author: naddy@openbsd.org +Date: Fri May 17 14:42:00 2024 +0000 - Wrap mkstemp calls with umask set/restore. + upstream: remove duplicate copy of relink kit for sshd-session - glibc versions 2.06 and earlier did not set a umask on files created by - mkstemp created the world-writable. Wrap mkstemp to set and restore - the umask. From Coverity (CIDs 291826 291886 291891), ok djm@ + OpenBSD-Commit-ID: 6d2ded4cd91d4d727c2b26e099b91ea935bed504 -commit 633d3dc2a1e9e2a013d019a0576a0771c8423713 -Author: jcs@openbsd.org -Date: Thu Mar 9 21:06:24 2023 +0000 +commit dcd79fa141311c287e0595ede684b7116122fae0 +Author: jsg@openbsd.org +Date: Fri May 17 06:42:04 2024 +0000 - upstream: modify parentheses in conditionals to make it clearer what is - - being assigned and what is being checked - - ok djm dtucker + upstream: remove prototypes with no matching function; ok djm@ - OpenBSD-Commit-ID: 19c10baa46ae559474409f75a5cb3d0eade7a9b8 + OpenBSD-Commit-ID: 6d9065dadea5f14a01bece0dbfe2fba1be31c693 -commit 733030840c4772f858de95d5940ec0c37663e8b0 -Author: dtucker@openbsd.org -Date: Thu Mar 9 07:11:05 2023 +0000 +commit 6454a05e7c6574d70adf17efe505a8581a86ca4f +Author: jsg@openbsd.org +Date: Fri May 17 06:38:00 2024 +0000 - upstream: Re-split the merge of the reorder-hostkeys test. - - In the kex_proposal_populate_entries change I merged the the check for - reordering hostkeys with the actual reordering, but kex_assemble_names - mutates options.hostkeyalgorithms which renders the check ineffective. - Put the check back where it was. Spotted and tested by jsg@, ok djm@ + upstream: remove externs for removed vars; ok djm@ - OpenBSD-Commit-ID: a7469f25a738db5567395d1881e32479a7ffc9de + OpenBSD-Commit-ID: f51ea791d45c15d4927eb4ae7d877ccc1e5a2aab -commit 54ac4ab2b53ce9fcb66b8250dee91c070e4167ed -Author: djm@openbsd.org -Date: Thu Mar 9 06:58:26 2023 +0000 +commit f3e4db4601ef7d2feb1d6f7447e432aaf353a616 +Author: deraadt@openbsd.org +Date: Fri May 17 06:11:17 2024 +0000 - upstream: include destination constraints for smartcard keys too. + upstream: -Werror was turned on (probably just for development), - Spotted by Luci Stanescu; ok deraadt@ markus@ + and this is a simple way to satisfy older gcc. - OpenBSD-Commit-ID: add879fac6903a1cb1d1e42c4309e5359c3d870f + OpenBSD-Commit-ID: 7f698df54384b437ce33ab7405f0b86c87019e86 -commit bfd1ad01d974a316b60622759ad17537fa2d92b4 -Author: Darren Tucker -Date: Thu Mar 9 18:24:54 2023 +1100 +commit 24a1f3e5ad6f4a49377d4c74c36637e9a239efd0 +Author: Damien Miller +Date: Fri May 17 14:50:43 2024 +1000 - Limit the number of PAM environment variables. - - xcalloc has its own limits, but these are specific to PAM. From - Coverity CID 405198, ok djm@ + attempt at updating RPM specs for sshd-session -commit a231414970e01a35f45a295d5f93698fa1249b28 -Author: Darren Tucker -Date: Thu Mar 9 18:19:44 2023 +1100 +commit 17b566eeb7a0c6acc9c48b35c08885901186f861 +Author: djm@openbsd.org +Date: Fri May 17 04:42:13 2024 +0000 - Limit the number of PAM environment variables. + upstream: g/c unused variable - From Coverity CID 405194, tweaks and ok djm@ + OpenBSD-Commit-ID: aa6ef0778a1f1bde0d73efba72a777c48d2bd010 -commit 36c6c3eff5e4a669ff414b9daf85f919666e8e03 -Author: dtucker@openbsd.org -Date: Wed Mar 8 06:21:32 2023 +0000 +commit 01fb82eb2aa0a4eaf5c394ea8bb37ea4c26f8a3f +Author: jsg@openbsd.org +Date: Fri May 17 02:39:11 2024 +0000 - upstream: Plug mem leak. Coverity CID 405196, ok djm@ + upstream: spelling; ok djm@ - OpenBSD-Commit-ID: 175f09349387c292f626da68f65f334faaa085f2 + OpenBSD-Commit-ID: bdea29bb3ed2a5a7782999c4c663b219d2270483 -commit dfb9b736e1ccf9e6b03eea21cd961f4fd0634c98 -Author: tb@openbsd.org -Date: Wed Mar 8 05:33:53 2023 +0000 +commit b88b690e99145a021fc1a1a116a11e0bce0594e7 +Author: djm@openbsd.org +Date: Fri May 17 01:45:22 2024 +0000 - upstream: ssh-pkcs11: synchronize error messages with errors - - A handful of error messages contained incorrect function names or - otherwise inaccurate descriptions. Fix them to match reality. - - input/ok djm + upstream: allow overriding the sshd-session binary path - OpenBSD-Commit-ID: 165a15db52f75b31e1804b043480c36af09f3411 + OpenBSD-Regress-ID: 5058cd1c4b6ca1a15474e33546142931d9f964da -commit 51875897b81b5c21b80c256a29597916edbde454 -Author: guenther@openbsd.org -Date: Wed Mar 8 04:43:12 2023 +0000 +commit a68f80f2511f0e0c5cef737a8284cc2dfabad818 +Author: anton@openbsd.org +Date: Wed Apr 3 06:01:11 2024 +0000 - upstream: Delete obsolete /* ARGSUSED */ lint comments. + upstream: Since ssh-agent(1) is only readable by root by now, use - ok miod@ millert@ + ssh(1) while generating data in tests. - OpenBSD-Commit-ID: 7be168a570264d59e96a7d2d22e927d45fee0e4c - -commit a76085bda883c2104afb33ab0334eca190927362 -Author: Darren Tucker -Date: Wed Mar 8 17:25:37 2023 +1100 - - Extra brackets to prevent warning. + OpenBSD-Regress-ID: 24eb40de2e6b0ace185caaba35e2d470331ffe68 -commit 147ae57d4dfa0508109f93b78a7d8b92819e1f83 +commit 92e55890314ce2b0be21a43ebcbc043b4abc232f Author: djm@openbsd.org -Date: Wed Mar 8 00:05:58 2023 +0000 +Date: Fri May 17 01:17:40 2024 +0000 - upstream: use RSA/SHA256 when testing usability of private key in + upstream: fix incorrect debug option name introduce in previous - agent; with/ok dtucker + commit - OpenBSD-Commit-ID: fe1382e2fdf23fcae631308e72342bad56066a56 + OpenBSD-Commit-ID: 66d69e22b1c072c694a7267c847f212284614ed3 -commit 27fd251bc906a763e70ce0f27c8abdf8bbd1e416 -Author: djm@openbsd.org -Date: Wed Mar 8 00:05:37 2023 +0000 +commit 4ad72878af7b6ec28da6e230e36a91650ebe84c1 +Author: deraadt@openbsd.org +Date: Fri May 17 00:33:25 2024 +0000 - upstream: use RSA/SHA256 when testing usability of private key; + upstream: construct and install a relink-kit for sshd-session ok - based on fix in bz3546 by Dmitry Belyavskiy; with/ok dtucker + djm - OpenBSD-Commit-ID: 0ef414cc363a832f9fab92a5da0234448bce2eba + OpenBSD-Commit-ID: 8b3820adb4da4e139c4b3cffbcc0bde9f08bf0c6 -commit eee9f3fc3d52ae7d2106929bb06b7f291fb0b81a -Author: djm@openbsd.org -Date: Tue Mar 7 21:47:42 2023 +0000 +commit 02e679a2cb3f6df8e9dbb1519ed578226485157f +Author: Damien Miller +Date: Fri May 17 12:21:27 2024 +1000 - upstream: refactor to be more readable top to bottom. Prompted by - - Coverity CID 405048 which was a false-positive fd leak; ok dtucker@ - - OpenBSD-Commit-ID: fc55ec2af622a017defb9b768bf26faefc792c00 + Makefile support for sshd-session -commit 42a06b29a4c99272bf690f9b3be520b08b448dc5 -Author: Darren Tucker -Date: Tue Mar 7 18:34:41 2023 +1100 +commit c0416035c5eaf70a8450d11c8833c5f7068ee7ad +Author: djm@openbsd.org +Date: Fri May 17 00:32:32 2024 +0000 - Add header changes missed in previous. + upstream: missing files from previous + + OpenBSD-Commit-ID: 4b7be4434d8799f02365552b641a7a70a7ebeb2f -commit 4710077096edff2e6926dd5b15bf586491d317db -Author: dtucker@openbsd.org -Date: Tue Mar 7 06:09:14 2023 +0000 +commit 03e3de416ed7c34faeb692967737be4a7bbe2eb5 +Author: djm@openbsd.org +Date: Fri May 17 00:30:23 2024 +0000 - upstream: Fix mem leak in environment setup. + upstream: Start the process of splitting sshd into separate - From jjelen at redhat.com via bz#2687, ok djm@ + binaries. This step splits sshd into a listener and a session binary. More + splits are planned. - OpenBSD-Commit-ID: 9f9e4ba3cac003e6f81da3bcebd1b9ec43e7f353 - -commit 03acc50d0ccb78fc91d1570de1cd0fdfea646028 -Author: dtucker@openbsd.org -Date: Mon Mar 6 12:15:47 2023 +0000 - - upstream: Unit test for kex_proposal_populate_entries. + After this changes, the listener binary will validate the configuration, + load the hostkeys, listen on port 22 and manage MaxStartups only. All + session handling will be performed by a new sshd-session binary that the + listener fork+execs. - OpenBSD-Regress-ID: bdb211d80d572a08bf14b49fe2a58b9ff265c006 - -commit 3f9231c2e1f374ebb08016ba00ea97b47c0ed20b -Author: djm@openbsd.org -Date: Tue Mar 7 05:37:26 2023 +0000 - - upstream: fix memory leak in process_read() path; Spotted by James + This reduces the listener process to the minimum necessary and sets us + up for future work on the sshd-session binary. + + feedback/ok markus@ deraadt@ - Robinson in GHPR363; ok markus@ + NB. if you're updating via source, please restart sshd after installing, + otherwise you run the risk of locking yourself out. - OpenBSD-Commit-ID: cdc2d98e6478b7e7f3a36976845adae3820429d8 + OpenBSD-Commit-ID: 43c04a1ab96cdbdeb53d2df0125a6d42c5f19934 -commit c5e6e890839ec520ab9301a92cba56303749dea2 +commit 1c0d81357921f8d3bab06841df649edac515ae5b Author: djm@openbsd.org -Date: Tue Mar 7 01:30:52 2023 +0000 +Date: Thu May 9 09:46:47 2024 +0000 - upstream: correct size for array argument when changing + upstream: simplify exit message handling, which was more complicated - UMAC_OUTPUT_LEN Coverity CID 291845; ok dtucker@ + than it needed to be because of unexpunged ssh1 remnants. ok markus@ - OpenBSD-Commit-ID: 2eb017d10705bb623d4418691f961c930eafaec0 + OpenBSD-Commit-ID: 8b0cd2c0dee75fb053718f442aa89510b684610b -commit 9641753e0fd146204d57b2a4165f552a81afade4 -Author: dtucker@openbsd.org -Date: Mon Mar 6 12:14:48 2023 +0000 +commit cbbbf76aa6cd54fce32eacce1300e7abcf9461d4 +Author: tobias@openbsd.org +Date: Mon May 6 19:26:17 2024 +0000 - upstream: Refactor creation of KEX proposal. - - This adds kex_proposal_populate_entries (and corresponding free) which - populates the KEX proposal array with dynamically allocated strings. - This replaces the previous mix of static and dynamic that has been the - source of previous leaks and bugs. Remove unused compat functions. - With & ok djm@. + upstream: remove SSH1 leftovers - OpenBSD-Commit-ID: f2f99da4aae2233cb18bf9c749320c5e040a9c7b - -commit aa59d6a489fb20973fa461d0fdb1110db412947b -Author: dtucker@openbsd.org -Date: Sun Mar 5 09:24:35 2023 +0000 - - upstream: Fix mem and FILE leaks in moduli screening. + Authored with Space Meyer - If multiple -Ocheckpoint= options are passed, the earlier ones would - be overwritten and leaked. If we use an input file that wasn't stdin, - close that. From Coverity CIDs 291884 and 291894. + ok djm - OpenBSD-Commit-ID: a4d9d15f572926f841788912e2b282485ad09e8b + OpenBSD-Commit-ID: 81db602e4cb407baae472689db1c222ed7b2afa3 -commit 23b8cb41767af99a1aac24589d1882d9c8c2c205 -Author: dtucker@openbsd.org -Date: Sun Mar 5 08:18:58 2023 +0000 +commit bc5dcb8ab9a4e8af54a724883732af378f42ea78 +Author: tobias@openbsd.org +Date: Tue Apr 30 15:40:43 2024 +0000 - upstream: Plug mem leak in moduli checkpoint option parsing. - - From Coverity CID 291894. + upstream: never close stdin - OpenBSD-Commit-ID: 9b1aba2d049741ae21c8dc4560a7e29ab17310f4 - -commit fc7f8f2188d4a4fc8ba77eddbe863c7665666db5 -Author: dtucker@openbsd.org -Date: Sun Mar 5 05:34:09 2023 +0000 - - upstream: Remove unused compat.h includes. + The sanitise_stdfd call makes sure that standard file descriptors are + open (if they were closed, they are connected with /dev/null). - We've previously removed a lot of the really old compatibility code, - and with it went the need to include compat.h in most of the files that - have it. + Do not close stdin in any case to prevent error messages when stdin is + read multiple times and to prevent later usage of fd 0 for connections, + e.g. - OpenBSD-Commit-ID: 5af8baa194be00a3092d17598e88a5b29f7ea2b4 - -commit 6c165c36246d8004c20e1df5cec4961a5ac422d6 -Author: dtucker@openbsd.org -Date: Sat Mar 4 03:22:59 2023 +0000 - - upstream: Use time_t for x11 timeout. + echo localhost | ssh-keyscan -f - -f - - Use time_t instead of u_int for remaining x11 timeout checks for 64bit - time_t safety. From Coverity CIDs 405197 and 405028, ok djm@ + While at it, make stdin-related error messages nicer. - OpenBSD-Commit-ID: 356685bfa1fc3d81bd95722d3fc47101cc1a4972 - -commit 4a3918f51bd2d968387e7aa87e33b32c78077fb4 -Author: dtucker@openbsd.org -Date: Fri Mar 3 10:23:42 2023 +0000 - - upstream: Ensure ms_remain is always initialized + Authored with Max Kunzelmann - similar to what we do in ssh_packet_write_wait. bz#2687, from jjelen - at redhat.com. + ok djm - OpenBSD-Commit-ID: a50e0541cf823f8d1c72f71ccde925d3dbe6dfac + OpenBSD-Commit-ID: 48e9b7938e2fa2f9bd47e6de6df66a31e0b375d3 -commit e44846a4487d2885ac7f2610be09b1e2bf52249b -Author: dtucker@openbsd.org -Date: Fri Mar 3 09:48:51 2023 +0000 +commit 6a42b70e56bef1aacdcdf06352396e837883e84f +Author: Damien Miller +Date: Wed May 8 09:43:59 2024 +1000 - upstream: Check for non-NULL before string - - comparison. From jjelen at redhat.com via bz#2687. - - OpenBSD-Commit-ID: 0d9b2e0cac88a311b5766b1aef737082583c285f + sync getrrsetbyname.c with recent upstream changes -commit 1842d523fae63b862ce8e60725c9b606cddb86a6 +commit 385ecb31e147dfea59c1c488a1d2011d3867e60e Author: djm@openbsd.org -Date: Fri Mar 3 05:00:34 2023 +0000 +Date: Tue Apr 30 06:23:51 2024 +0000 - upstream: guard against getsockname(-1, ...) from Coverity CID + upstream: fix home-directory extension implementation, it always + + returned the current user's home directory contrary to the spec. - 291832 + Patch from Jakub Jelen via GHPR477 - OpenBSD-Commit-ID: e58d5227327917d189229b7f0b37d2780f360d5f + OpenBSD-Commit-ID: 5afd775eab7f9cbe222d7fbae4c793de6c3b3d28 -commit 78571a5fe9847d40d7f220c92b707574ae9ec4ce +commit 14e2b16bc67ffcc188906f65008667e22f73d103 Author: djm@openbsd.org -Date: Fri Mar 3 04:36:20 2023 +0000 +Date: Tue Apr 30 06:16:55 2024 +0000 - upstream: some options are not first-match-wins. Mention that there + upstream: flush stdout after writing "sftp>" prompt when not using + + editline. - are exceptions at the start of the manpage and label some of them in the - option description. + From Alpine Linux via GHPR480 - OpenBSD-Commit-ID: 3b74728446fa6fc8742769eeb8c3674e233e84c4 + OpenBSD-Commit-ID: 80bdc7ffe0358dc090eb9b93e6dedb2b087b24cd -commit d1c1b3272e8895a96c4f5889bd6e07a8525bd9f1 +commit 2e69a724051488e3fb3cd11531c4b5bc1764945b Author: djm@openbsd.org -Date: Fri Mar 3 04:34:49 2023 +0000 +Date: Tue Apr 30 05:53:03 2024 +0000 - upstream: actually print "channeltimeout none" in config dump mode; + upstream: stricter validation of messaging socket fd number; disallow - spotted via Coverity CID 405022 + usage of stderr. Based on GHPR492 by RealHurrison - OpenBSD-Commit-ID: b074b52bf138b75f08264e8da15880b29c7a630f - -commit 8bf61e95610b48192d4e1720cc15d9004617301d -Author: Darren Tucker -Date: Fri Mar 3 14:50:03 2023 +1100 - - Add Coverity badges. + OpenBSD-Commit-ID: 73dbbe82ea16f73ce1d044d3232bc869ae2f2ce8 -commit 93291bd723959adf462b1df958106cf07a7734dd -Author: dtucker@openbsd.org -Date: Fri Mar 3 03:12:24 2023 +0000 +commit da757b022bf18c6f7d04e685a10cd96ed00f83da +Author: djm@openbsd.org +Date: Tue Apr 30 05:45:56 2024 +0000 - upstream: Check return values of dup2. Spotted by Coverity, ok djm@ + upstream: add missing reserved fields to key constraint protocol - OpenBSD-Commit-ID: 19fb1b53072826d00c67df677731d2f6c1dd602b - -commit e37261dff33af23f37202cfce0848d36f5c1055c -Author: dtucker@openbsd.org -Date: Fri Mar 3 02:37:58 2023 +0000 - - upstream: Use time_t for x11_refuse_time timeout. We need + documentation. - SSH_TIME_T_MAX for this, so move from misc.c to misc.h so it's available. - Fixes a Coverity warning for 64bit time_t safety, ok djm@ + from Wiktor Kwapisiewicz via GHPR487 - OpenBSD-Commit-ID: c69c4c3152cdaab953706db4ccf4d5fd682f7d8d + OpenBSD-Commit-ID: 0dfb69998cfdb3fa00cbb0e7809e7d2f6126e3df -commit 32755a98c29114b13f4c9d47454bbb265b932ad7 -Author: dtucker@openbsd.org -Date: Fri Mar 3 02:34:29 2023 +0000 +commit 16d0b82fa08038f35f1b3630c70116979f49784f +Author: Damien Miller +Date: Tue Apr 30 12:39:34 2024 +1000 - upstream: Check return value from fctnl and warn on failure. - - Spotted by Coverity, ok djm@ - - OpenBSD-Commit-ID: 2097c7db3cf657f1e3a6c5077041bacc63143cab + depend -commit 5fc60e8246c36b8255f72a937ebe9787b39648c6 -Author: dtucker@openbsd.org -Date: Thu Mar 2 11:10:27 2023 +0000 +commit 66aaa678dbe59aa21d0d9d89a3596ecedde0254b +Author: djm@openbsd.org +Date: Tue Apr 30 02:14:10 2024 +0000 - upstream: Remove SUDO in proxy command wrapper. Anything that needs + upstream: correctly restore sigprocmask around ppoll() reported - sudo is already run by it, and it breaks if root isn't in sudoers. + by Tõivo Leedjärv; ok deraadt@ - OpenBSD-Regress-ID: 6cf22fda32a89c16915f31a6ed9bbdbef2a3bac9 + OpenBSD-Commit-ID: c0c0f89de5294a166578f071eade2501929c4686 -commit 0d514659b23a257247491179cfbb53a6dd64e164 -Author: dtucker@openbsd.org -Date: Thu Mar 2 08:24:41 2023 +0000 +commit 80fb0eb21551aed3aebb009ab20aeffeb01e44e0 +Author: djm@openbsd.org +Date: Tue Apr 30 02:10:49 2024 +0000 - upstream: Fix breakage on dhgex test. + upstream: add explict check for server hostkey type against - This was due to the sshd logs being written to the wrong log file. - While there, make save_debug_logs less verbose, write the name of the - tarball to regress.log and use $SUDO to remove the old symlinks (which - shouldn't be needed, but won't hurt). Initial problem spotted by anton@. + HostkeyAlgorithms. Allows HostkeyAlgorithms to disable implicit fallback from + certificate keys to plain keys. ok markus@ - OpenBSD-Regress-ID: 9c44fb9cd418e6ff31165e7a6c1f9f11a6d19f5b + OpenBSD-Commit-ID: 364087e4a395ff9b2f42bf3aefdb2090bb23643a -commit 860201201d4ae655702807966901682cff30a171 -Author: dtucker@openbsd.org -Date: Thu Mar 2 08:14:52 2023 +0000 +commit 5b28096d31ff7d80748fc845553a4aef5bb05d86 +Author: jsg@openbsd.org +Date: Tue Apr 23 13:34:50 2024 +0000 - upstream: Quote grep and log message better. + upstream: correct indentation; no functional change ok tb@ - OpenBSD-Regress-ID: 3823d9063127169736aa274b1784cb28e15b64d4 + OpenBSD-Commit-ID: dd9702fd43de546bc6a3f4f025c74d6f3692a0d4 -commit 03a03c6002525f5ad9c8fc874a5d5826a35d9858 -Author: dtucker@openbsd.org -Date: Thu Mar 2 06:41:56 2023 +0000 +commit fd3cb8a82784e05f621dea5b56ac6f89bc53c067 +Author: semarie@openbsd.org +Date: Thu Apr 4 16:00:51 2024 +0000 - upstream: Always call fclose on checkpoints. + upstream: set right mode on ssh-agent at boot-time - In the case of an fprintf failure we would not call fclose which would - leak the FILE pointer. While we're there, try to clean up the temp file - on failure. Spotted by Coverity, ok djm@ + which sthen@ + ok deraadt@ - OpenBSD-Commit-ID: 73c7ccc5d4fcc235f54c6b20767a2815408525ef + OpenBSD-Commit-ID: 662b5056a2c6171563e1626f9c69f27862b5e7af -commit 13fe8f9785e6d90400ce548939a0b0ddc11fcb3c -Author: dtucker@openbsd.org -Date: Wed Mar 1 21:54:50 2023 +0000 +commit 54343a260e3aa4bceca1852dde31cd08e2abd82b +Author: deraadt@openbsd.org +Date: Tue Apr 2 12:22:38 2024 +0000 - upstream: Remove old log symlinks + upstream: Oops, incorrect hex conversion spotted by claudio. - before creating new ones. In -portable some platforms don't like - overwriting existing symlinks. + While here try to improve how it reads a bit better. Surprising the + regression tests didn't spot this error, maybe it fails to roundtrip the + values. - OpenBSD-Regress-ID: 7e7ddc0beb73e945e1c4c58d51c8a125b518120f - -commit 131fcbcaffd1e3bcf5ab766ec497b5d768955310 -Author: Darren Tucker -Date: Wed Mar 1 23:23:02 2023 +1100 - - Adjust test jobs for new log directory. + OpenBSD-Commit-ID: 866cfcc1955aef8f3fc32da0b70c353a1b859f2e -commit a6f4ac8a2baf77e5361cfa017d0dc250d1409bec -Author: dtucker@openbsd.org -Date: Wed Mar 1 09:29:32 2023 +0000 +commit ec78c31409590ad74efc194f886273ed080a545a +Author: deraadt@openbsd.org +Date: Tue Apr 2 10:02:08 2024 +0000 - upstream: Rework logging for the regression tests. - - Previously we would log to ssh.log and sshd.log, but that is insufficient - for tests that have more than one concurent ssh/sshd. - - Instead, we'll log to separate datestamped files in a $OBJ/log/ and - leave a symlink at the previous location pointing at the most recent - instance with an entry in regress.log showing which files were created - at each point. This should be sufficient to reconstruct what happened - even for tests that use multiple instances of each program. If the test - fails, tar up all of the logs for later analysis. + upstream: for parse_ipqos(), use strtonum() instead of mostly - This will let us also capture the output from some of the other tools - which was previously sent to /dev/null although most of those will be - in future commits. + idiomatic strtoul(), but wow it's so gross. ok djm - OpenBSD-Regress-ID: f802aa9e7fa51d1a01225c05fb0412d015c33e24 + OpenBSD-Commit-ID: cec14a76af2eb7b225300c80fc0e21052be67b05 -commit 8ead62ed5e86c7df597d8604f332f49cd1527b85 -Author: dtucker@openbsd.org -Date: Tue Feb 28 21:31:50 2023 +0000 +commit 8176e1a6c2e6da9361a7abb6fbf6c23c299f495b +Author: deraadt@openbsd.org +Date: Tue Apr 2 09:56:58 2024 +0000 - upstream: fatal out if allocating banner string fails to avoid + upstream: can shortcut by returning strtonum() value directly; ok - potential null deref later in sscanf. Spotted by Coverity, ok deraadt@ + djm - OpenBSD-Commit-ID: 74e8d228ac00552e96e9e968dfcccf8dd1f46ad5 + OpenBSD-Commit-ID: 7bb2dd3d6d1f288dac14247d1de446e3d7ba8b8e -commit 44ca56ba0b3f531f1d85730cc701097cd49e6868 -Author: dtucker@openbsd.org -Date: Tue Feb 28 08:45:24 2023 +0000 +commit 9f543d7022a781f80bb696f9d73f1d1c6f9e31d6 +Author: deraadt@openbsd.org +Date: Tue Apr 2 09:52:14 2024 +0000 - upstream: Explicitly ignore return from fchmod + upstream: rewrite convtime() to use a isdigit-scanner and - similar to other calls to prevent warning. + strtonum() instead of strange strtoul can might be fooled by garage + characters. passes regress/usr.bin/ssh/unittests/misc ok djm - OpenBSD-Commit-ID: fdc5287dcee0860b5a493186414226c655b0eb0a + OpenBSD-Commit-ID: 4b1ef826bb16047aea3f3bdcb385b72ffd450abc -commit 803392933a3a6f09f834aa5f0c2aab06a3b382f4 -Author: dtucker@openbsd.org -Date: Mon Feb 27 22:12:40 2023 +0000 +commit 8673137f780d8d9e4cda3c4605cb5d88d5cea271 +Author: claudio@openbsd.org +Date: Tue Apr 2 09:48:24 2024 +0000 - upstream: Plug mem leak on globbed ls error path. + upstream: Remove unused ptr[3] char array in pkcs11_decode_hex. - Spotted by Coverity, ok deraadt@ + OK deraadt@ - OpenBSD-Commit-ID: de28476025db29820a9a2e56e98b964d8a02861c + OpenBSD-Commit-ID: 3d14433e39fd558f662d3b0431c4c555ef920481 -commit aa33b4d396abf47a2a45f982f28d054fb1dcb5c3 -Author: Darren Tucker -Date: Mon Feb 27 21:04:22 2023 +1100 +commit c7fec708f331f108343d69e4d74c9a5d86d6cfe7 +Author: deraadt@openbsd.org +Date: Tue Apr 2 09:32:28 2024 +0000 - Cast time_t's in debug output to long long. + upstream: Replace non-idiomatic strtoul(, 16) to parse a region - Should fix Coverity warning about truncation of 64bit time_t. - -commit b0fd60a9de62a03189ad57d0c07f0ac51dc00e95 -Author: Darren Tucker -Date: Mon Feb 27 17:28:59 2023 +1100 - - Do shadow expiry calcs using "long long". + of 2-character hex sequences with a low-level replacement designed just for + the task. ok djm - Coverity flags these as potentially not 64bit time_t safe so use - long long for the calculations and debug output. ok djm@ + OpenBSD-Commit-ID: 67bab8b8a4329a19a0add5085eacd6f4cc215e85 -commit 01dbeb3084d714bbd001ff9d03b9de542e8cdf58 -Author: Damien Miller -Date: Mon Feb 27 17:07:52 2023 +1100 +commit 019a5f483b0f588da6270ec401d0b4bb35032f3f +Author: deraadt@openbsd.org +Date: Tue Apr 2 09:29:31 2024 +0000 - avoid clash between for getopt's struct option + upstream: Use strtonum() instead of severely non-idomatic - Since we don't use getopt_long() nothing outside the getopt() - implementation itself uses this structure, so move it into the - source to remove it from visibility and clashes with libc's + strtoul() In particular this will now reject trailing garbage, ie. + '12garbage'. ok djm - ok dtucker@ + OpenBSD-Commit-ID: c82d95e3ccbfedfc91a8041c2f8bf0cf987d1501 -commit eb88d07c43afe407094e7d609248d85a15e148ef -Author: Darren Tucker -Date: Sat Feb 25 14:45:41 2023 +1100 +commit 8231ca046fa39ea4eb99b79e0a6e09dec50ac952 +Author: deraadt@openbsd.org +Date: Mon Apr 1 15:50:17 2024 +0000 - Revert explicit chmods on private keys. + upstream: also create a relink kit for ssh-agent, since it is a - This should no longer be needed on Cygwin test runners due to previous - commit. - -commit 52b75db61030a6c8baf66b73644380cf3f58e26a -Author: Darren Tucker -Date: Sat Feb 25 14:43:28 2023 +1100 - - Remove extended ACLs from working dirs. + long-running setgid program carrying keys with some (not very powerful) + communication channels. solution for testing the binary from dtucker. + agreement from djm. Will add it into /etc/rc in a few days. - This should allow umask to work as expected and prevent tests from - failing due to excessive permissions on private keys. + OpenBSD-Commit-ID: 2fe8d707ae35ba23c7916adcb818bb5b66837ba0 -commit 0c5d4c843df5605b043a758d69f9a611ef63c479 -Author: Darren Tucker -Date: Fri Feb 24 13:44:13 2023 +1100 +commit bf7bf50bd6a14e49c9c243cb8f4de31e555a5a2e +Author: deraadt@openbsd.org +Date: Mon Apr 1 15:48:16 2024 +0000 - Explicitly set permissions on user and host keys. + upstream: new-style relink kit for sshd. The old scheme created + + a Makefile by concatenating two Makefiles and was incredibly fragile. In the + new way a narrow-purposed install.sh script is created and shipped with the + objects. A recently commited /etc/rc script understands these files. - On cygwin, the umask might not be sufficient. Should fix tests on - Github runners. + OpenBSD-Commit-ID: ef9341d5a50f0d33e3a6fbe995e92964bc7ef2d3 -commit 6c9fc9d7a9f7abf82c3294d74e6d4a25735862ce -Author: djm@openbsd.org -Date: Wed Feb 22 03:56:43 2023 +0000 +commit 00e63688920905e326d8667cb47f17a156b6dc8f +Author: renmingshuai +Date: Fri Apr 12 10:20:49 2024 +0800 - upstream: fix progressmeter corruption on wide displays; bz3534 - - feedback/ok dtucker@ + Shell syntax fix (leftover from a sync). - OpenBSD-Commit-ID: f4affee067cec7c182f3e0b307d758e0472762a3 + Signed-off-by: renmingshuai -commit fe0bd3cde9665d364e5eedd2c2c2e60d4cdc3786 -Author: dtucker@openbsd.org -Date: Tue Feb 21 06:48:18 2023 +0000 +commit 2eded551ba96e66bc3afbbcc883812c2eac02bd7 +Author: Darren Tucker +Date: Thu Apr 25 13:20:19 2024 +1000 - upstream: fseek to end of known_hosts before writing to it. + Merge flags for OpenSSL 3.x versions. - POSIX and ANSI C require that applications call fseek or similar between - read and writing to a RW file. OpenBSD doesn't enforce this, but some - (System V derived) platforms need this to prevent it from writing a - spurious extra byte (in this case, a newline). ok djm@ deraadt@ + OpenSSL has moved to 3.4 which we don't currently accept. Based on + the OpenSSL versioning policy[0] it looks like all of the 3.x versions + should work with OpenSSH, so remove the distinction in configure and + accept all of them. - OpenBSD-Commit-ID: 33e680dcd8110582a93a40a8491024e961f45137 + [0] https://openssl.org/policies/general/versioning-policy.html -commit 357fb8ae14c07cd025eeed66e73de91bab569849 +commit 8673245918081c6d1dc7fb3733c8eb2c5a902c5e Author: Darren Tucker -Date: Tue Feb 21 17:51:09 2023 +1100 +Date: Thu Apr 25 13:19:03 2024 +1000 - Also run unit tests on AIX VMs. - - In the past these tests took too long, but these days it only adds - about 5 min to the run. + Remove 9.6 branch from status page. -commit 17781aaa5188ee1477f7779b280d105512e3dbed +commit 70d43049747fa3c66cf876d52271859407cec2fa Author: Darren Tucker -Date: Tue Feb 21 17:38:55 2023 +1100 +Date: Thu Apr 25 13:16:58 2024 +1000 - Wrap stdint.h inside ifdef. + Update LibreSSL and OpenSSL versions tested. + + Update LibreSSL versions to current releases (3.8.4 & 3.9.1). + Add newly-released OpenSSL 3.3.0, and add tests against the 3.1 and + 3.3 branches. -commit ef798bad38505f7bf1b5fa5c0843dfc5a2b192b9 -Author: Mayank Sharma -Date: Mon Feb 20 17:37:15 2023 +0530 +commit 88351eca17dcc55189991ba60e50819b6d4193c1 +Author: 90 +Date: Fri Apr 5 19:36:06 2024 +0100 - Add includes to ptimeout test. - - Fixes test failures on AIX due to type mismatches. + Fix missing header for systemd notification -commit ab69dda05d5268454209f529fa80f477e60d846a -Author: Darren Tucker -Date: Mon Feb 20 18:24:39 2023 +1100 +commit 08f579231cd38a1c657aaa6ddeb8ab57a1fd4f5c +Author: Damien Miller +Date: Wed Apr 3 14:40:32 2024 +1100 - Always use the openssl binary configure tells us. + notify systemd on listen and reload - This fixes tests on platforms that do not have the openssl tool - installed at all. + Standalone implementation that does not depend on libsystemd. + With assistance from Luca Boccassi, and feedback/testing from Colin + Watson. bz2641 diff --git a/INSTALL b/INSTALL index f99d1e2..96b2994 100644 --- a/INSTALL +++ b/INSTALL @@ -19,12 +19,15 @@ A working installation of zlib: Zlib 1.1.4 or 1.2.1.2 or greater (earlier 1.2.x versions have problems): https://zlib.net/ -libcrypto from either of LibreSSL or OpenSSL. Building without libcrypto -is supported but severely restricts the available ciphers and algorithms. +libcrypto from one of LibreSSL, OpenSSL, AWS-LC or BoringSSL. Building +without libcrypto is supported but severely restricts the available +ciphers and algorithms. - LibreSSL (https://www.libressl.org/) 3.1.0 or greater - OpenSSL (https://www.openssl.org) 1.1.1 or greater + - AWS-LC (https://github.com/aws/aws-lc) + - BoringSSL (https://github.com/google/boringssl) -LibreSSL/OpenSSL should be compiled as a position-independent library +libcrypto should be compiled as a position-independent library (i.e. -fPIC, eg by configuring OpenSSL as "./config [options] -fPIC" or LibreSSL as "CFLAGS=-fPIC ./configure") otherwise OpenSSH will not be able to link with it. If you must use a non-position-independent @@ -41,15 +44,17 @@ direct support of /dev/random, or failing that, either prngd or egd. PRNGD: If your system lacks kernel-based random collection, the use of Lutz -Jaenicke's PRNGd is recommended. It requires that libcrypto be configured -to support it. +Jaenicke's PRNGd is recommended. If you are using libcrypto it requires +that the libcrypto is configured to support it. If you are building +--without-openssl then the --with-prngd-socket option must match the +socket provided by prngd. http://prngd.sourceforge.net/ EGD: The Entropy Gathering Daemon (EGD) supports the same interface as prngd. -It also supported only if libcrypto is configured to support it. +The same caveats about configuration for prngd also apply. http://egd.sourceforge.net/ @@ -94,8 +99,8 @@ http://nlnetlabs.nl/projects/ldns/ Autoconf: If you modify configure.ac or configure doesn't exist (eg if you checked -the code out of git yourself) then you will need autoconf-2.69 and -automake-1.16.1 to rebuild the automatically generated files by running +the main git branch) then you will need autoconf-2.69 and automake-1.16.1 +or newer to rebuild the automatically generated files by running "autoreconf". Earlier versions may also work but this is not guaranteed. http://www.gnu.org/software/autoconf/ @@ -243,7 +248,7 @@ manually using the following commands: ssh-keygen -t [type] -f /etc/ssh/ssh_host_key -N "" -for each of the types you wish to generate (rsa, dsa or ecdsa) or +for each of the types you wish to generate (rsa, ed25519 or ecdsa) or ssh-keygen -A diff --git a/Makefile.in b/Makefile.in index 4243006..2aac879 100644 --- a/Makefile.in +++ b/Makefile.in @@ -18,13 +18,13 @@ top_srcdir=@top_srcdir@ abs_top_srcdir=@abs_top_srcdir@ abs_top_builddir=@abs_top_builddir@ -DESTDIR= VPATH=@srcdir@ SSH_PROGRAM=@bindir@/ssh ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass SFTP_SERVER=$(libexecdir)/sftp-server SSH_KEYSIGN=$(libexecdir)/ssh-keysign SSHD_SESSION=$(libexecdir)/sshd-session +SSHD_AUTH=$(libexecdir)/sshd-auth SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper SSH_SK_HELPER=$(libexecdir)/ssh-sk-helper PRIVSEP_PATH=@PRIVSEP_PATH@ @@ -32,6 +32,8 @@ SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ STRIP_OPT=@STRIP_OPT@ TEST_SHELL=@TEST_SHELL@ BUILDDIR=@abs_top_builddir@ +SK_STANDALONE=@SK_STANDALONE@ +COMPATINCLUDES="$(BUILDDIR)/@COMPATINCLUDES@" PATHS= -DSSHDIR=\"$(sysconfdir)\" \ -D_PATH_SSH_PROGRAM=\"$(SSH_PROGRAM)\" \ @@ -39,6 +41,7 @@ PATHS= -DSSHDIR=\"$(sysconfdir)\" \ -D_PATH_SFTP_SERVER=\"$(SFTP_SERVER)\" \ -D_PATH_SSH_KEY_SIGN=\"$(SSH_KEYSIGN)\" \ -D_PATH_SSHD_SESSION=\"$(SSHD_SESSION)\" \ + -D_PATH_SSHD_AUTH=\"$(SSHD_AUTH)\" \ -D_PATH_SSH_PKCS11_HELPER=\"$(SSH_PKCS11_HELPER)\" \ -D_PATH_SSH_SK_HELPER=\"$(SSH_SK_HELPER)\" \ -D_PATH_SSH_PIDDIR=\"$(piddir)\" \ @@ -48,7 +51,7 @@ CC=@CC@ LD=@LD@ CFLAGS=@CFLAGS@ CFLAGS_NOPIE=@CFLAGS_NOPIE@ -CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ +CPPFLAGS=-I. -I$(srcdir) -I$(COMPATINCLUDES) @CPPFLAGS@ $(PATHS) @DEFS@ PICFLAG=@PICFLAG@ LIBS=@LIBS@ CHANNELLIBS=@CHANNELLIBS@ @@ -57,6 +60,7 @@ GSSLIBS=@GSSLIBS@ SSHDLIBS=@SSHDLIBS@ LIBEDIT=@LIBEDIT@ LIBFIDO2=@LIBFIDO2@ +LIBWTMPDB=@LIBWTMPDB@ AR=@AR@ AWK=@AWK@ RANLIB=@RANLIB@ @@ -71,16 +75,7 @@ MKDIR_P=@MKDIR_P@ .SUFFIXES: .lo -TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) - -XMSS_OBJS=\ - ssh-xmss.o \ - sshkey-xmss.o \ - xmss_commons.o \ - xmss_fast.o \ - xmss_hash.o \ - xmss_hash_address.o \ - xmss_wots.o +TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(EXEEXT) sshd-auth$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) $(SK_STANDALONE) LIBOPENSSH_OBJS=\ ssh_api.o \ @@ -91,8 +86,7 @@ LIBOPENSSH_OBJS=\ sshbuf-misc.o \ sshbuf-getput-crypto.o \ krl.o \ - bitmap.o \ - ${XMSS_OBJS} + bitmap.o LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ authfd.o authfile.o \ @@ -102,29 +96,31 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ log.o match.o moduli.o nchan.o packet.o \ readpass.o ttymodes.o xmalloc.o addr.o addrmatch.o \ atomicio.o dispatch.o mac.o misc.o utf8.o \ - monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-ecdsa-sk.o \ + monitor_fdpass.o rijndael.o ssh-ecdsa.o ssh-ecdsa-sk.o \ ssh-ed25519-sk.o ssh-rsa.o dh.o \ - msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ - ssh-pkcs11.o smult_curve25519_ref.o \ + msg.o dns.o entropy.o gss-genr.o umac.o umac128.o \ + smult_curve25519_ref.o \ poly1305.o chacha.o cipher-chachapoly.o cipher-chachapoly-libcrypto.o \ ssh-ed25519.o digest-openssl.o digest-libc.o \ - hmac.o ed25519.o hash.o \ + hmac.o ed25519.o ed25519-openssl.o \ kex.o kex-names.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ kexgexc.o kexgexs.o \ kexsntrup761x25519.o kexmlkem768x25519.o sntrup761.o kexgen.o \ sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ - sshbuf-io.o + sshbuf-io.o misc-agent.o ssherr-libcrypto.o + +P11OBJS= ssh-pkcs11-client.o SKOBJS= ssh-sk-client.o SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ - sshconnect.o sshconnect2.o mux.o $(SKOBJS) + sshconnect.o sshconnect2.o mux.o ssh-pkcs11.o $(SKOBJS) SSHDOBJS=sshd.o \ platform-listen.o \ servconf.o sshpty.o srclimit.o groupaccess.o auth2-methods.o \ dns.o fatal.o compat.o utf8.o authfd.o canohost.o \ - $(SKOBJS) + $(P11OBJS) $(SKOBJS) SSHD_SESSION_OBJS=sshd-session.o auth-rhosts.o auth-passwd.o \ audit.o audit-bsm.o audit-linux.o platform.o \ @@ -137,29 +133,42 @@ SSHD_SESSION_OBJS=sshd-session.o auth-rhosts.o auth-passwd.o \ auth2-gss.o gss-serv.o gss-serv-krb5.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o \ sftp-server.o sftp-common.o \ - sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ - sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ - sandbox-solaris.o uidswap.o $(SKOBJS) + uidswap.o platform-listen.o $(P11OBJS) $(SKOBJS) + +SSHD_AUTH_OBJS=sshd-auth.o \ + auth2-methods.o \ + auth-rhosts.o auth-passwd.o sshpty.o sshlogin.o servconf.o \ + serverloop.o auth.o auth2.o auth-options.o session.o auth2-chall.o \ + groupaccess.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ + auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-pubkeyfile.o \ + auth2-gss.o gss-serv.o gss-serv-krb5.o \ + monitor_wrap.o auth-krb5.o \ + audit.o audit-bsm.o audit-linux.o platform.o \ + loginrec.o auth-pam.o auth-shadow.o auth-sia.o \ + sandbox-null.o sandbox-rlimit.o sandbox-darwin.o \ + sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-solaris.o \ + sftp-server.o sftp-common.o \ + uidswap.o $(P11OBJS) $(SKOBJS) -SFTP_CLIENT_OBJS=sftp-common.o sftp-client.o sftp-glob.o +SFTP_CLIENT_OBJS=sftp-common.o sftp-client.o sftp-glob.o ssherr-nolibcrypto.o SCP_OBJS= scp.o progressmeter.o $(SFTP_CLIENT_OBJS) -SSHADD_OBJS= ssh-add.o $(SKOBJS) +SSHADD_OBJS= ssh-add.o $(P11OBJS) $(SKOBJS) -SSHAGENT_OBJS= ssh-agent.o ssh-pkcs11-client.o $(SKOBJS) +SSHAGENT_OBJS= ssh-agent.o $(P11OBJS) $(SKOBJS) -SSHKEYGEN_OBJS= ssh-keygen.o sshsig.o $(SKOBJS) +SSHKEYGEN_OBJS= ssh-keygen.o sshsig.o ssh-pkcs11.o $(SKOBJS) -SSHKEYSIGN_OBJS=ssh-keysign.o readconf.o uidswap.o $(SKOBJS) +SSHKEYSIGN_OBJS=ssh-keysign.o readconf.o uidswap.o $(P11OBJS) $(SKOBJS) P11HELPER_OBJS= ssh-pkcs11-helper.o ssh-pkcs11.o $(SKOBJS) -SKHELPER_OBJS= ssh-sk-helper.o ssh-sk.o sk-usbhid.o +SKHELPER_OBJS= ssh-sk-helper.o ssh-sk.o sk-usbhid.o ssherr-nolibcrypto.o -SSHKEYSCAN_OBJS=ssh-keyscan.o $(SKOBJS) +SSHKEYSCAN_OBJS=ssh-keyscan.o $(P11OBJS) $(SKOBJS) -SFTPSERVER_OBJS=sftp-common.o sftp-server.o sftp-server-main.o +SFTPSERVER_OBJS=sftp-common.o sftp-server.o sftp-server-main.o ssherr-nolibcrypto.o SFTP_OBJS= sftp.o sftp-usergroup.o progressmeter.o $(SFTP_CLIENT_OBJS) @@ -178,7 +187,6 @@ PATHSUBS = \ -e 's|/etc/shosts.equiv|$(sysconfdir)/shosts.equiv|g' \ -e 's|/etc/ssh/ssh_host_key|$(sysconfdir)/ssh_host_key|g' \ -e 's|/etc/ssh/ssh_host_ecdsa_key|$(sysconfdir)/ssh_host_ecdsa_key|g' \ - -e 's|/etc/ssh/ssh_host_dsa_key|$(sysconfdir)/ssh_host_dsa_key|g' \ -e 's|/etc/ssh/ssh_host_rsa_key|$(sysconfdir)/ssh_host_rsa_key|g' \ -e 's|/etc/ssh/ssh_host_ed25519_key|$(sysconfdir)/ssh_host_ed25519_key|g' \ -e 's|/var/run/sshd.pid|$(piddir)/sshd.pid|g' \ @@ -218,7 +226,10 @@ sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS) $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(CHANNELLIBS) sshd-session$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHD_SESSION_OBJS) - $(LD) -o $@ $(SSHD_SESSION_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) + $(LD) -o $@ $(SSHD_SESSION_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) $(LIBWTMPDB) + +sshd-auth$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHD_AUTH_OBJS) + $(LD) -o $@ $(SSHD_AUTH_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) $(LIBWTMPDB) scp$(EXEEXT): $(LIBCOMPAT) libssh.a $(SCP_OBJS) $(LD) -o $@ $(SCP_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) @@ -254,6 +265,16 @@ sftp$(EXEEXT): $(LIBCOMPAT) libssh.a $(SFTP_OBJS) logintest: logintest.o $(LIBCOMPAT) libssh.a loginrec.o $(LD) -o $@ logintest.o $(LDFLAGS) loginrec.o -lopenbsd-compat -lssh $(LIBS) +# compile libssh objects with -fPIC for use in the sk_libfido2 shared library +LIBSSH_PIC_OBJS=$(LIBSSH_OBJS:.o=.lo) +libssh-pic.a: $(LIBSSH_PIC_OBJS) + $(AR) rv $@ $(LIBSSH_PIC_OBJS) + $(RANLIB) $@ + +$(SK_STANDALONE): $(srcdir)/sk-usbhid.c $(LIBCOMPAT) libssh-pic.a + $(CC) -o $@ -shared $(CFLAGS_NOPIE) $(CPPFLAGS) -DSK_STANDALONE $(PICFLAG) $(srcdir)/sk-usbhid.c \ + libssh-pic.a $(LDFLAGS_NOPIE) -lopenbsd-compat $(LIBS) $(LIBFIDO2) $(CHANNELLIBS) + $(MANPAGES): $(MANPAGES_IN) if test "$(MANTYPE)" = "cat"; then \ manpage=$(srcdir)/`echo $@ | sed 's/\.[1-9]\.out$$/\.0/'`; \ @@ -267,7 +288,7 @@ $(MANPAGES): $(MANPAGES_IN) $(FIXPATHSCMD) $${manpage} | $(FIXALGORITHMSCMD) > $@; \ fi -$(CONFIGFILES): $(CONFIGFILES_IN) +$(CONFIGFILES): $(CONFIGFILES_IN) Makefile conffile=`echo $@ | sed 's/.out$$//'`; \ $(FIXPATHSCMD) $(srcdir)/$${conffile} > $@ @@ -306,7 +327,8 @@ clean: regressclean rm -f regress/unittests/utf8/test_utf8$(EXEEXT) rm -f regress/misc/sk-dummy/*.o rm -f regress/misc/sk-dummy/*.lo - rm -f regress/misc/sk-dummy/sk-dummy.so + rm -f regress/misc/ssh-verify-attestation/ssh-verify-attestation$(EXEEXT) + rm -f regress/misc/ssh-verify-attestation/*.o (cd openbsd-compat && $(MAKE) clean) distclean: regressclean @@ -314,6 +336,7 @@ distclean: regressclean rm -f *.out core opensshd.init openssh.xml rm -f Makefile buildpkg.sh config.h config.status rm -f survey.sh openbsd-compat/regress/Makefile *~ + rm -rf openbsd-compat/include rm -rf autom4te.cache rm -f regress/check-perm rm -f regress/mkdtemp @@ -344,6 +367,8 @@ distclean: regressclean rm -f regress/misc/sk-dummy/*.o rm -f regress/misc/sk-dummy/*.lo rm -f regress/misc/sk-dummy/sk-dummy.so + rm -f regress/misc/ssh-verify-attestation/ssh-verify-attestation$(EXEEXT) + rm -f regress/misc/ssh-verify-attestation/*.o (cd openbsd-compat && $(MAKE) distclean) if test -d pkg ; then \ rm -fr pkg ; \ @@ -411,6 +436,7 @@ install-files: $(INSTALL) -m 0755 $(STRIP_OPT) ssh-keyscan$(EXEEXT) $(DESTDIR)$(bindir)/ssh-keyscan$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) sshd$(EXEEXT) $(DESTDIR)$(sbindir)/sshd$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) sshd-session$(EXEEXT) $(DESTDIR)$(SSHD_SESSION)$(EXEEXT) + $(INSTALL) -m 0755 $(STRIP_OPT) sshd-auth$(EXEEXT) $(DESTDIR)$(SSHD_AUTH)$(EXEEXT) $(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign$(EXEEXT) $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) ssh-pkcs11-helper$(EXEEXT) $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) ssh-sk-helper$(EXEEXT) $(DESTDIR)$(SSH_SK_HELPER)$(EXEEXT) @@ -461,7 +487,6 @@ host-key: ssh-keygen$(EXEEXT) fi host-key-force: ssh-keygen$(EXEEXT) ssh$(EXEEXT) - ./ssh-keygen -t dsa -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N "" ./ssh-keygen -t rsa -f $(DESTDIR)$(sysconfdir)/ssh_host_rsa_key -N "" ./ssh-keygen -t ed25519 -f $(DESTDIR)$(sysconfdir)/ssh_host_ed25519_key -N "" if ./ssh -Q key | grep ecdsa >/dev/null ; then \ @@ -519,11 +544,12 @@ regress-prep: $(MKDIR_P) `pwd`/regress/unittests/sshsig $(MKDIR_P) `pwd`/regress/unittests/utf8 $(MKDIR_P) `pwd`/regress/misc/sk-dummy + $(MKDIR_P) `pwd`/regress/misc/ssh-verify-attestation [ -f `pwd`/regress/Makefile ] || \ ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile REGRESSLIBS=libssh.a $(LIBCOMPAT) -TESTLIBS=$(LIBS) $(CHANNELLIBS) +TESTLIBS=$(LIBS) $(CHANNELLIBS) @TESTLIBS@ regress/modpipe$(EXEEXT): $(srcdir)/regress/modpipe.c $(REGRESSLIBS) $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/modpipe.c \ @@ -579,7 +605,7 @@ UNITTESTS_TEST_SSHKEY_OBJS=\ regress/unittests/sshkey/common.o \ regress/unittests/sshkey/test_file.o \ regress/unittests/sshkey/test_sshkey.o \ - $(SKOBJS) + $(P11OBJS) $(SKOBJS) regress/unittests/sshkey/test_sshkey$(EXEEXT): ${UNITTESTS_TEST_SSHKEY_OBJS} \ regress/unittests/test_helper/libtest_helper.a libssh.a @@ -590,7 +616,7 @@ regress/unittests/sshkey/test_sshkey$(EXEEXT): ${UNITTESTS_TEST_SSHKEY_OBJS} \ UNITTESTS_TEST_SSHSIG_OBJS=\ sshsig.o \ regress/unittests/sshsig/tests.o \ - $(SKOBJS) + $(P11OBJS) $(SKOBJS) regress/unittests/sshsig/test_sshsig$(EXEEXT): ${UNITTESTS_TEST_SSHSIG_OBJS} \ regress/unittests/test_helper/libtest_helper.a libssh.a @@ -610,7 +636,7 @@ regress/unittests/bitmap/test_bitmap$(EXEEXT): ${UNITTESTS_TEST_BITMAP_OBJS} \ UNITTESTS_TEST_AUTHOPT_OBJS=\ regress/unittests/authopt/tests.o \ auth-options.o \ - $(SKOBJS) + $(P11OBJS) $(SKOBJS) regress/unittests/authopt/test_authopt$(EXEEXT): \ ${UNITTESTS_TEST_AUTHOPT_OBJS} \ @@ -633,7 +659,7 @@ UNITTESTS_TEST_KEX_OBJS=\ regress/unittests/kex/tests.o \ regress/unittests/kex/test_kex.o \ regress/unittests/kex/test_proposal.o \ - $(SKOBJS) + $(P11OBJS) $(SKOBJS) regress/unittests/kex/test_kex$(EXEEXT): ${UNITTESTS_TEST_KEX_OBJS} \ regress/unittests/test_helper/libtest_helper.a libssh.a @@ -644,7 +670,7 @@ regress/unittests/kex/test_kex$(EXEEXT): ${UNITTESTS_TEST_KEX_OBJS} \ UNITTESTS_TEST_HOSTKEYS_OBJS=\ regress/unittests/hostkeys/tests.o \ regress/unittests/hostkeys/test_iterate.o \ - $(SKOBJS) + $(P11OBJS) $(SKOBJS) regress/unittests/hostkeys/test_hostkeys$(EXEEXT): \ ${UNITTESTS_TEST_HOSTKEYS_OBJS} \ @@ -671,7 +697,9 @@ UNITTESTS_TEST_MISC_OBJS=\ regress/unittests/misc/test_argv.o \ regress/unittests/misc/test_strdelim.o \ regress/unittests/misc/test_hpdelim.o \ - regress/unittests/misc/test_ptimeout.o + regress/unittests/misc/test_ptimeout.o \ + regress/unittests/misc/test_xextendf.o \ + regress/unittests/misc/test_misc.o regress/unittests/misc/test_misc$(EXEEXT): \ ${UNITTESTS_TEST_MISC_OBJS} \ @@ -694,7 +722,7 @@ regress/unittests/utf8/test_utf8$(EXEEXT): \ SK_DUMMY_OBJS=\ regress/misc/sk-dummy/sk-dummy.lo \ regress/misc/sk-dummy/fatal.lo \ - ed25519.lo hash.lo + ed25519.lo ed25519-openssl.lo SK_DUMMY_LIBRARY=@SK_DUMMY_LIBRARY@ @@ -705,6 +733,16 @@ regress/misc/sk-dummy/sk-dummy.so: $(SK_DUMMY_OBJS) $(CC) $(CFLAGS) $(CPPFLAGS) $(PICFLAG) -shared -o $@ $(SK_DUMMY_OBJS) \ -L. -Lopenbsd-compat -lopenbsd-compat $(LDFLAGS_NOPIE) $(TESTLIBS) +SSH_VERIFY_ATTESTATION_OBJS=\ + regress/misc/ssh-verify-attestation/ssh-verify-attestation.o \ + $(P11OBJS) $(SKOBJS) + +ssh-verify-attestation: regress/misc/ssh-verify-attestation/ssh-verify-attestation$(EXEEXT) + +regress/misc/ssh-verify-attestation/ssh-verify-attestation$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSH_VERIFY_ATTESTATION_OBJS) + $(LD) -o $@ $(SSH_VERIFY_ATTESTATION_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS) $(LIBFIDO2) + + regress-binaries: regress-prep $(LIBCOMPAT) \ regress/modpipe$(EXEEXT) \ regress/timestamp$(EXEEXT) \ @@ -738,6 +776,15 @@ unit: regress-unit-binaries OBJ="$(BUILDDIR)/regress" \ $@ && echo $@ tests passed +unit-bench: regress-unit-binaries + cd $(srcdir)/regress || exit $$?; \ + $(MAKE) \ + .CURDIR="$(abs_top_srcdir)/regress" \ + .OBJDIR="$(BUILDDIR)/regress" \ + OBJ="$(BUILDDIR)/regress" $@ + +TEST_SSH_SSHD="$(BUILDDIR)/sshd" + interop-tests t-exec file-tests extra-tests: regress-prep regress-binaries $(TARGETS) cd $(srcdir)/regress || exit $$?; \ EGREP='@EGREP@' \ @@ -752,8 +799,9 @@ interop-tests t-exec file-tests extra-tests: regress-prep regress-binaries $(TAR TEST_MALLOC_OPTIONS="@TEST_MALLOC_OPTIONS@" \ TEST_SSH_SCP="$(BUILDDIR)/scp" \ TEST_SSH_SSH="$(BUILDDIR)/ssh" \ - TEST_SSH_SSHD="$(BUILDDIR)/sshd" \ + TEST_SSH_SSHD="$(TEST_SSH_SSHD)" \ TEST_SSH_SSHD_SESSION="$(BUILDDIR)/sshd-session" \ + TEST_SSH_SSHD_AUTH="$(BUILDDIR)/sshd-auth" \ TEST_SSH_SSHAGENT="$(BUILDDIR)/ssh-agent" \ TEST_SSH_SSHADD="$(BUILDDIR)/ssh-add" \ TEST_SSH_SSHKEYGEN="$(BUILDDIR)/ssh-keygen" \ @@ -771,6 +819,7 @@ interop-tests t-exec file-tests extra-tests: regress-prep regress-binaries $(TAR TEST_SSH_DROPBEARKEY="@DROPBEARKEY@" \ TEST_SSH_DROPBEARCONVERT="@DROPBEARCONVERT@" \ TEST_SSH_DBCLIENT="@DBCLIENT@" \ + TEST_SSH_TMUX="@TMUX@" \ TEST_SSH_IPV6="@TEST_SSH_IPV6@" \ TEST_SSH_UTF8="@TEST_SSH_UTF8@" \ TEST_SHELL="$(TEST_SHELL)" \ diff --git a/PROTOCOL b/PROTOCOL index 2638779..06081f8 100644 --- a/PROTOCOL +++ b/PROTOCOL @@ -33,15 +33,11 @@ The method is documented in: https://www.openssh.com/txt/draft-miller-secsh-compression-delayed-00.txt -1.3. transport: New public key algorithms "ssh-rsa-cert-v01@openssh.com", - "ssh-dsa-cert-v01@openssh.com", - "ecdsa-sha2-nistp256-cert-v01@openssh.com", - "ecdsa-sha2-nistp384-cert-v01@openssh.com" and - "ecdsa-sha2-nistp521-cert-v01@openssh.com" +1.3. transport: Certificate key algorithms OpenSSH introduces new public key algorithms to support certificate authentication for users and host keys. These methods are documented -in the file PROTOCOL.certkeys +in at https://datatracker.ietf.org/doc/draft-miller-ssh-cert/ 1.4. transport: Elliptic Curve cryptography @@ -82,29 +78,20 @@ contains: 1.6 transport: AES-GCM OpenSSH supports the AES-GCM algorithm as specified in RFC 5647. -Because of problems with the specification of the key exchange -the behaviour of OpenSSH differs from the RFC as follows: +Because of problems with the design of the algorithm negotiation in this +RFC, OpenSSH (and other SSH implementations) use different rules as +described in: -AES-GCM is only negotiated as the cipher algorithms -"aes128-gcm@openssh.com" or "aes256-gcm@openssh.com" and never as -an MAC algorithm. Additionally, if AES-GCM is selected as the cipher -the exchanged MAC algorithms are ignored and there doesn't have to be -a matching MAC. +https://datatracker.ietf.org/doc/draft-miller-sshm-aes-gcm/ 1.7 transport: chacha20-poly1305@openssh.com authenticated encryption OpenSSH supports authenticated encryption using ChaCha20 and Poly1305 -as described in PROTOCOL.chacha20poly1305. +as described in: -1.8 transport: curve25519-sha256@libssh.org key exchange algorithm +https://datatracker.ietf.org/doc/draft-ietf-sshm-chacha20-poly1305/ -OpenSSH supports the use of ECDH in Curve25519 for key exchange as -described at: -http://git.libssh.org/users/aris/libssh.git/plain/doc/curve25519-sha256@libssh.org.txt?h=curve25519 - -This is identical to curve25519-sha256 as later published in RFC8731. - -1.9 transport: ping facility +1.8 transport: ping facility OpenSSH implements a transport level ping message SSH2_MSG_PING and a corresponding SSH2_MSG_PONG reply. @@ -137,34 +124,16 @@ than as a named global or channel request to allow pings with very short packet lengths, which would not be possible with other approaches. -1.10 transport: strict key exchange extension - -OpenSSH supports a number of transport-layer hardening measures under -a "strict KEX" feature. This feature is signalled similarly to the -RFC8308 ext-info feature: by including a additional algorithm in the -initial SSH2_MSG_KEXINIT kex_algorithms field. The client may append -"kex-strict-c-v00@openssh.com" to its kex_algorithms and the server -may append "kex-strict-s-v00@openssh.com". These pseudo-algorithms -are only valid in the initial SSH2_MSG_KEXINIT and MUST be ignored -if they are present in subsequent SSH2_MSG_KEXINIT packets. - -When an endpoint that supports this extension observes this algorithm -name in a peer's KEXINIT packet, it MUST make the following changes to -the protocol: - -a) During initial KEX, terminate the connection if out-of-sequence - packet or any message that is not strictly required by KEX is - received. This includes terminating the connection if the first - packet received is not SSH2_MSG_KEXINIT. Unexpected packets for - the purpose of strict KEX include messages that are otherwise - valid at any time during the connection such as SSH2_MSG_DEBUG, - SSH2_MSG_IGNORE or SSH2_MSG_UNIMPLEMENTED. -b) After sending or receiving a SSH2_MSG_NEWKEYS message, reset the - packet sequence number to zero. This behaviour persists for the - duration of the connection (i.e. not just the first - SSH2_MSG_NEWKEYS). - -1.11 transport: SSH2_MSG_EXT_INFO during user authentication +1.9 transport: strict key exchange extension + +OpenSSH supports a number of transport-layer hardening measures +designed to thwart the so-called "Terrapin" attack against the +early SSH protocol. These are collectively referred to as +"strict KEX" and documented in an Internet-Draft: + +https://datatracker.ietf.org/doc/draft-miller-sshm-strict-kex/ + +1.10 transport: SSH2_MSG_EXT_INFO during user authentication This protocol extension allows the SSH2_MSG_EXT_INFO to be sent during user authentication. RFC8308 does allow a second @@ -369,52 +338,9 @@ and "hostkeys-prove-00@openssh.com" OpenSSH supports a protocol extension allowing a server to inform a client of all its protocol v.2 host keys after user-authentication -has completed. - - byte SSH_MSG_GLOBAL_REQUEST - string "hostkeys-00@openssh.com" - char 0 /* want-reply */ - string[] hostkeys - -Upon receiving this message, a client should check which of the -supplied host keys are present in known_hosts. - -Note that the server may send key types that the client does not -support. The client should disregard such keys if they are received. - -If the client identifies any keys that are not present for the host, -it should send a "hostkeys-prove@openssh.com" message to request the -server prove ownership of the private half of the key. - - byte SSH_MSG_GLOBAL_REQUEST - string "hostkeys-prove-00@openssh.com" - char 1 /* want-reply */ - string[] hostkeys - -When a server receives this message, it should generate a signature -using each requested key over the following: - - string "hostkeys-prove-00@openssh.com" - string session identifier - string hostkey - -These signatures should be included in the reply, in the order matching -the hostkeys in the request: - - byte SSH_MSG_REQUEST_SUCCESS - string[] signatures - -When the client receives this reply (and not a failure), it should -validate the signatures and may update its known_hosts file, adding keys -that it has not seen before and deleting keys for the server host that -are no longer offered. +has completed. This is documented in an Internet-Draft -These extensions let a client learn key types that it had not previously -encountered, thereby allowing it to potentially upgrade from weaker -key algorithms to better ones. It also supports graceful key rotation: -a server may offer multiple keys of the same type for a period (to -give clients an opportunity to learn them using this extension) before -removing the deprecated key from those offered. +https://datatracker.ietf.org/doc/draft-miller-sshm-hostkey-update/ 2.6. connection: SIGINFO support for "signal" channel request @@ -765,15 +691,15 @@ authorized_keys files, are formatted as a single line of text consisting of the public key algorithm name followed by a base64-encoded key blob. The public key blob (before base64 encoding) is the same format used for the encoding of public keys sent on the wire: as described in RFC4253 -section 6.6 for RSA and DSA keys, RFC5656 section 3.1 for ECDSA keys -and the "New public key formats" section of PROTOCOL.certkeys for the -OpenSSH certificate formats. +section 6.6 for RSA keys, RFC5656 section 3.1 for ECDSA keys and +https://datatracker.ietf.org/doc/draft-miller-ssh-cert/ +for the OpenSSH certificate formats. 5.2 Private key format OpenSSH private keys, as generated by ssh-keygen(1) use the format described in PROTOCOL.key by default. As a legacy option, PEM format -(RFC7468) private keys are also supported for RSA, DSA and ECDSA keys +(RFC7468) private keys are also supported for RSA and ECDSA keys and were the default format before OpenSSH 7.8. 5.3 KRL format @@ -792,4 +718,4 @@ master instance and later clients. OpenSSH extends the usual agent protocol. These changes are documented in the PROTOCOL.agent file. -$OpenBSD: PROTOCOL,v 1.55 2024/01/08 05:05:15 djm Exp $ +$OpenBSD: PROTOCOL,v 1.60 2026/02/09 22:09:48 dtucker Exp $ diff --git a/PROTOCOL.agent b/PROTOCOL.agent index 9ae16bf..2af749b 100644 --- a/PROTOCOL.agent +++ b/PROTOCOL.agent @@ -1,5 +1,5 @@ The SSH agent protocol is described in -https://tools.ietf.org/html/draft-miller-ssh-agent +https://datatracker.ietf.org/doc/draft-ietf-sshm-ssh-agent/ This file documents OpenSSH's extensions to the agent protocol. @@ -73,17 +73,6 @@ identities and, in particular, signature requests will check the key constraints against the session-bind@openssh.com bindings recorded for the agent connection over which they were received. -3. SSH_AGENT_CONSTRAIN_MAXSIGN key constraint - -This key constraint allows communication to an agent of the maximum -number of signatures that may be made with an XMSS key. The format of -the constraint is: - - byte SSH_AGENT_CONSTRAIN_MAXSIGN (0x03) - uint32 max_signatures - -This option is only valid for XMSS keys. - 3. associated-certs-v00@openssh.com key constraint extension The key constraint extension allows certificates to be associated @@ -115,4 +104,4 @@ A SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED will return SSH_AGENT_SUCCESS if any key (plain private or certificate) was successfully loaded, or SSH_AGENT_FAILURE if no key was loaded. -$OpenBSD: PROTOCOL.agent,v 1.23 2024/04/30 05:45:56 djm Exp $ +$OpenBSD: PROTOCOL.agent,v 1.25 2025/08/29 03:50:38 djm Exp $ diff --git a/PROTOCOL.certkeys b/PROTOCOL.certkeys deleted file mode 100644 index 68622e6..0000000 --- a/PROTOCOL.certkeys +++ /dev/null @@ -1,321 +0,0 @@ -This document describes a simple public-key certificate authentication -system for use by SSH. - -Background ----------- - -The SSH protocol currently supports a simple public key authentication -mechanism. Unlike other public key implementations, SSH eschews the use -of X.509 certificates and uses raw keys. This approach has some benefits -relating to simplicity of configuration and minimisation of attack -surface, but it does not support the important use-cases of centrally -managed, passwordless authentication and centrally certified host keys. - -These protocol extensions build on the simple public key authentication -system already in SSH to allow certificate-based authentication. The -certificates used are not traditional X.509 certificates, with numerous -options and complex encoding rules, but something rather more minimal: a -key, some identity information and usage options that have been signed -with some other trusted key. - -A sshd server may be configured to allow authentication via certified -keys, by extending the existing ~/.ssh/authorized_keys mechanism to -allow specification of certification authority keys in addition to -raw user keys. The ssh client will support automatic verification of -acceptance of certified host keys, by adding a similar ability to -specify CA keys in ~/.ssh/known_hosts. - -All certificate types include certification information along with the -public key that is used to sign challenges. In OpenSSH, ssh-keygen -performs the CA signing operation. - -Certified keys are represented using new key types: - - ssh-rsa-cert-v01@openssh.com - ssh-dss-cert-v01@openssh.com - ecdsa-sha2-nistp256-cert-v01@openssh.com - ecdsa-sha2-nistp384-cert-v01@openssh.com - ecdsa-sha2-nistp521-cert-v01@openssh.com - ssh-ed25519-cert-v01@openssh.com - -Two additional types exist for RSA certificates to force use of -SHA-2 signatures (SHA-256 and SHA-512 respectively): - - rsa-sha2-256-cert-v01@openssh.com - rsa-sha2-512-cert-v01@openssh.com - -These RSA/SHA-2 types should not appear in keys at rest or transmitted -on the wire, but do appear in a SSH_MSG_KEXINIT's host-key algorithms -field or in the "public key algorithm name" field of a "publickey" -SSH_USERAUTH_REQUEST to indicate that the signature will use the -specified algorithm. - -Protocol extensions -------------------- - -The SSH wire protocol includes several extensibility mechanisms. -These modifications shall take advantage of namespaced public key -algorithm names to add support for certificate authentication without -breaking the protocol - implementations that do not support the -extensions will simply ignore them. - -Authentication using the new key formats described below proceeds -using the existing SSH "publickey" authentication method described -in RFC4252 section 7. - -New public key formats ----------------------- - -The certificate key types take a similar high-level format (note: data -types and encoding are as per RFC4251 section 5). The serialised wire -encoding of these certificates is also used for storing them on disk. - -#define SSH_CERT_TYPE_USER 1 -#define SSH_CERT_TYPE_HOST 2 - -RSA certificate - - string "ssh-rsa-cert-v01@openssh.com" - string nonce - mpint e - mpint n - uint64 serial - uint32 type - string key id - string valid principals - uint64 valid after - uint64 valid before - string critical options - string extensions - string reserved - string signature key - string signature - -DSA certificate - - string "ssh-dss-cert-v01@openssh.com" - string nonce - mpint p - mpint q - mpint g - mpint y - uint64 serial - uint32 type - string key id - string valid principals - uint64 valid after - uint64 valid before - string critical options - string extensions - string reserved - string signature key - string signature - -ECDSA certificate - - string "ecdsa-sha2-nistp256-cert-v01@openssh.com" | - "ecdsa-sha2-nistp384-cert-v01@openssh.com" | - "ecdsa-sha2-nistp521-cert-v01@openssh.com" - string nonce - string curve - string public_key - uint64 serial - uint32 type - string key id - string valid principals - uint64 valid after - uint64 valid before - string critical options - string extensions - string reserved - string signature key - string signature - -ED25519 certificate - - string "ssh-ed25519-cert-v01@openssh.com" - string nonce - string pk - uint64 serial - uint32 type - string key id - string valid principals - uint64 valid after - uint64 valid before - string critical options - string extensions - string reserved - string signature key - string signature - -The nonce field is a CA-provided random bitstring of arbitrary length -(but typically 16 or 32 bytes) included to make attacks that depend on -inducing collisions in the signature hash infeasible. - -e and n are the RSA exponent and public modulus respectively. - -p, q, g, y are the DSA parameters as described in FIPS-186-2. - -curve and public key are respectively the ECDSA "[identifier]" and "Q" -defined in section 3.1 of RFC5656. - -pk is the encoded Ed25519 public key as defined by RFC8032. - -serial is an optional certificate serial number set by the CA to -provide an abbreviated way to refer to certificates from that CA. -If a CA does not wish to number its certificates, it must set this -field to zero. - -type specifies whether this certificate is for identification of a user -or a host using a SSH_CERT_TYPE_... value. - -key id is a free-form text field that is filled in by the CA at the time -of signing; the intention is that the contents of this field are used to -identify the identity principal in log messages. - -"valid principals" is a string containing zero or more principals as -strings packed inside it. These principals list the names for which this -certificate is valid; hostnames for SSH_CERT_TYPE_HOST certificates and -usernames for SSH_CERT_TYPE_USER certificates. As a special case, a -zero-length "valid principals" field means the certificate is valid for -any principal of the specified type. - -"valid after" and "valid before" specify a validity period for the -certificate. Each represents a time in seconds since 1970-01-01 -00:00:00. A certificate is considered valid if: - - valid after <= current time < valid before - -critical options is a set of zero or more key options encoded as -below. All such options are "critical" in the sense that an implementation -must refuse to authorise a key that has an unrecognised option. - -extensions is a set of zero or more optional extensions. These extensions -are not critical, and an implementation that encounters one that it does -not recognise may safely ignore it. - -Generally, critical options are used to control features that restrict -access where extensions are used to enable features that grant access. -This ensures that certificates containing unknown restrictions do not -inadvertently grant access while allowing new protocol features to be -enabled via extensions without breaking certificates' backwards -compatibility. - -The reserved field is currently unused and is ignored in this version of -the protocol. - -The signature key field contains the CA key used to sign the -certificate. The valid key types for CA keys are ssh-rsa, -ssh-dss, ssh-ed25519 and the ECDSA types ecdsa-sha2-nistp256, -ecdsa-sha2-nistp384, ecdsa-sha2-nistp521. "Chained" certificates, where -the signature key type is a certificate type itself are NOT supported. -Note that it is possible for a RSA certificate key to be signed by a -Ed25519 or ECDSA CA key and vice-versa. - -signature is computed over all preceding fields from the initial string -up to, and including the signature key. Signatures are computed and -encoded according to the rules defined for the CA's public key algorithm -(RFC4253 section 6.6 for ssh-rsa and ssh-dss, RFC5656 for the ECDSA -types, and RFC8032 for Ed25519). - -Critical options ----------------- - -The critical options section of the certificate specifies zero or more -options on the certificate's validity. The format of this field -is a sequence of zero or more tuples: - - string name - string data - -Options must be lexically ordered by "name" if they appear in the -sequence. Each named option may only appear once in a certificate. - -The name field identifies the option and the data field encodes -option-specific information (see below). All options are -"critical"; if an implementation does not recognise a option, -then the validating party should refuse to accept the certificate. - -Custom options should append the originating author or organisation's -domain name to the option name, e.g. "my-option@example.com". - -No critical options are defined for host certificates at present. The -supported user certificate options and the contents and structure of -their data fields are: - -Name Format Description ------------------------------------------------------------------------------ -force-command string Specifies a command that is executed - (replacing any the user specified on the - ssh command-line) whenever this key is - used for authentication. - -source-address string Comma-separated list of source addresses - from which this certificate is accepted - for authentication. Addresses are - specified in CIDR format (nn.nn.nn.nn/nn - or hhhh::hhhh/nn). - If this option is not present, then - certificates may be presented from any - source address. - -verify-required empty Flag indicating that signatures made - with this certificate must assert FIDO - user verification (e.g. PIN or - biometric). This option only makes sense - for the U2F/FIDO security key types that - support this feature in their signature - formats. - -Extensions ----------- - -The extensions section of the certificate specifies zero or more -non-critical certificate extensions. The encoding and ordering of -extensions in this field is identical to that of the critical options, -as is the requirement that each name appear only once. - -If an implementation does not recognise an extension, then it should -ignore it. - -Custom options should append the originating author or organisation's -domain name to the option name, e.g. "my-option@example.com". - -No extensions are defined for host certificates at present. The -supported user certificate extensions and the contents and structure of -their data fields are: - -Name Format Description ------------------------------------------------------------------------------ -no-touch-required empty Flag indicating that signatures made - with this certificate need not assert - FIDO user presence. This option only - makes sense for the U2F/FIDO security - key types that support this feature in - their signature formats. - -permit-X11-forwarding empty Flag indicating that X11 forwarding - should be permitted. X11 forwarding will - be refused if this option is absent. - -permit-agent-forwarding empty Flag indicating that agent forwarding - should be allowed. Agent forwarding - must not be permitted unless this - option is present. - -permit-port-forwarding empty Flag indicating that port-forwarding - should be allowed. If this option is - not present, then no port forwarding will - be allowed. - -permit-pty empty Flag indicating that PTY allocation - should be permitted. In the absence of - this option PTY allocation will be - disabled. - -permit-user-rc empty Flag indicating that execution of - ~/.ssh/rc should be permitted. Execution - of this script will not be permitted if - this option is not present. - -$OpenBSD: PROTOCOL.certkeys,v 1.19 2021/06/05 13:47:00 naddy Exp $ diff --git a/PROTOCOL.chacha20poly1305 b/PROTOCOL.chacha20poly1305 deleted file mode 100644 index 0bfff28..0000000 --- a/PROTOCOL.chacha20poly1305 +++ /dev/null @@ -1,107 +0,0 @@ -This document describes the chacha20-poly1305@openssh.com authenticated -encryption cipher supported by OpenSSH. - -Background ----------- - -ChaCha20 is a stream cipher designed by Daniel Bernstein and described -in [1]. It operates by permuting 128 fixed bits, 128 or 256 bits of key, -a 64 bit nonce and a 64 bit counter into 64 bytes of output. This output -is used as a keystream, with any unused bytes simply discarded. - -Poly1305[2], also by Daniel Bernstein, is a one-time Carter-Wegman MAC -that computes a 128 bit integrity tag given a message and a single-use -256 bit secret key. - -The chacha20-poly1305@openssh.com combines these two primitives into an -authenticated encryption mode. The construction used is based on that -proposed for TLS by Adam Langley in [3], but differs in the layout of -data passed to the MAC and in the addition of encryption of the packet -lengths. - -Negotiation ------------ - -The chacha20-poly1305@openssh.com offers both encryption and -authentication. As such, no separate MAC is required. If the -chacha20-poly1305@openssh.com cipher is selected in key exchange, -the offered MAC algorithms are ignored and no MAC is required to be -negotiated. - -Detailed Construction ---------------------- - -The chacha20-poly1305@openssh.com cipher requires 512 bits of key -material as output from the SSH key exchange. This forms two 256 bit -keys (K_1 and K_2), used by two separate instances of chacha20. -The first 256 bits constitute K_2 and the second 256 bits become -K_1. - -The instance keyed by K_1 is a stream cipher that is used only -to encrypt the 4 byte packet length field. The second instance, -keyed by K_2, is used in conjunction with poly1305 to build an AEAD -(Authenticated Encryption with Associated Data) that is used to encrypt -and authenticate the entire packet. - -Two separate cipher instances are used here so as to keep the packet -lengths confidential but not create an oracle for the packet payload -cipher by decrypting and using the packet length prior to checking -the MAC. By using an independently-keyed cipher instance to encrypt the -length, an active attacker seeking to exploit the packet input handling -as a decryption oracle can learn nothing about the payload contents or -its MAC (assuming key derivation, ChaCha20 and Poly1305 are secure). - -The AEAD is constructed as follows: for each packet, generate a Poly1305 -key by taking the first 256 bits of ChaCha20 stream output generated -using K_2, an IV consisting of the packet sequence number encoded as an -uint64 under the SSH wire encoding rules and a ChaCha20 block counter of -zero. The K_2 ChaCha20 block counter is then set to the little-endian -encoding of 1 (i.e. {1, 0, 0, 0, 0, 0, 0, 0}) and this instance is used -for encryption of the packet payload. - -Packet Handling ---------------- - -When receiving a packet, the length must be decrypted first. When 4 -bytes of ciphertext length have been received, they may be decrypted -using the K_1 key, a nonce consisting of the packet sequence number -encoded as a uint64 under the usual SSH wire encoding and a zero block -counter to obtain the plaintext length. - -Once the entire packet has been received, the MAC MUST be checked -before decryption. A per-packet Poly1305 key is generated as described -above and the MAC tag calculated using Poly1305 with this key over the -ciphertext of the packet length and the payload together. The calculated -MAC is then compared in constant time with the one appended to the -packet and the packet decrypted using ChaCha20 as described above (with -K_2, the packet sequence number as nonce and a starting block counter of -1). - -To send a packet, first encode the 4 byte length and encrypt it using -K_1. Encrypt the packet payload (using K_2) and append it to the -encrypted length. Finally, calculate a MAC tag and append it. - -Rekeying --------- - -ChaCha20 must never reuse a {key, nonce} for encryption nor may it be -used to encrypt more than 2^70 bytes under the same {key, nonce}. The -SSH Transport protocol (RFC4253) recommends a far more conservative -rekeying every 1GB of data sent or received. If this recommendation -is followed, then chacha20-poly1305@openssh.com requires no special -handling in this area. - -References ----------- - -[1] "ChaCha, a variant of Salsa20", Daniel Bernstein - http://cr.yp.to/chacha/chacha-20080128.pdf - -[2] "The Poly1305-AES message-authentication code", Daniel Bernstein - http://cr.yp.to/mac/poly1305-20050329.pdf - -[3] "ChaCha20 and Poly1305 based Cipher Suites for TLS", Adam Langley - http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-03 - -$OpenBSD: PROTOCOL.chacha20poly1305,v 1.5 2020/02/21 00:04:43 dtucker Exp $ - diff --git a/README b/README index 8593619..e15b391 100644 --- a/README +++ b/README @@ -1,19 +1,19 @@ -See https://www.openssh.com/releasenotes.html#9.9p2 for the release +See https://www.openssh.com/releasenotes.html#10.3p1 for the release notes. Please read https://www.openssh.com/report.html for bug reporting -instructions and note that we do not use Github for bug reporting or -patch/pull-request management. +instructions and note that we do not use Github for bug reporting. This is the port of OpenBSD's excellent OpenSSH[0] to Linux and other Unices. OpenSSH is based on the last free version of Tatu Ylonen's sample -implementation with all patent-encumbered algorithms removed (to -external libraries), all known security bugs fixed, new features -reintroduced and many other clean-ups. OpenSSH has been created by -Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt, -and Dug Song. It has a homepage at https://www.openssh.com/ +implementation with all patent-encumbered algorithms removed (to external +libraries), all known security bugs fixed, new features reintroduced and +many other clean-ups. OpenSSH was created by Aaron Campbell, Bob Beck, +Markus Friedl, Niels Provos, Theo de Raadt, and Dug Song, and has been +developed and maintained by Andre Lucas, Ben Lindstom, Damien Miller, +Darren Tucker and Tim Rice. It has a homepage at https://www.openssh.com/ This port consists of the re-introduction of autoconf support, PAM support, EGD/PRNGD support and replacements for OpenBSD library @@ -23,10 +23,6 @@ FreeBSD, NetBSD, OpenBSD, OpenServer, Solaris and UnixWare. This version actively tracks changes in the OpenBSD CVS repository. -The PAM support is now more functional than the popular packages of -commercial ssh-1.2.x. It checks "account" and "session" modules for -all logins, not just when using password authentication. - There is now several mailing lists for this port of OpenSSH. Please refer to https://www.openssh.com/list.html for details on how to join. diff --git a/README.md b/README.md index 9431b0f..1cfcd7b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,10 @@ # Portable OpenSSH -[![C/C++ CI](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml/badge.svg)](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml) -[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/openssh.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:openssh) +[![C/C++ CI](../../actions/workflows/c-cpp.yml/badge.svg)](../../actions/workflows/c-cpp.yml) +[![VM CI](../../actions/workflows/vm.yml/badge.svg)](../../actions/workflows/vm.yml) +[![C/C++ CI self-hosted](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml/badge.svg)](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml) +[![CIFuzz](../../actions/workflows/cifuzz.yml/badge.svg)](../../actions/workflows/cifuzz.yml) +[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/openssh.svg)](https://issues.oss-fuzz.com/issues?q="Project:+openssh"+is:open) [![Coverity Status](https://scan.coverity.com/projects/21341/badge.svg)](https://scan.coverity.com/projects/openssh-portable) OpenSSH is a complete implementation of the SSH protocol (version 2) for secure remote login, command execution and file transfer. It includes a client ``ssh`` and server ``sshd``, file transfer utilities ``scp`` and ``sftp`` as well as tools for key generation (``ssh-keygen``), run-time key storage (``ssh-agent``) and a number of supporting programs. @@ -31,7 +34,7 @@ Stable release tarballs are available from a number of [download mirrors](https: Portable OpenSSH is built using autoconf and make. It requires a working C compiler, standard library and headers. -``libcrypto`` from either [LibreSSL](https://www.libressl.org/) or [OpenSSL](https://www.openssl.org) may also be used. OpenSSH may be built without either of these, but the resulting binaries will have only a subset of the cryptographic algorithms normally available. +``libcrypto`` from one of [LibreSSL](https://www.libressl.org/), [OpenSSL](https://www.openssl.org), [AWS-LC](https://github.com/aws/aws-lc) or [BoringSSL](https://github.com/google/boringssl) may also be used. OpenSSH may be built without either of these, but the resulting binaries will have only a subset of the cryptographic algorithms normally available. [zlib](https://www.zlib.net/) is optional; without it transport compression is not supported. @@ -41,7 +44,7 @@ In addition, certain platforms and build-time options may require additional dep ### Building a release -Releases include a pre-built copy of the ``configure`` script and may be built using: +Release tarballs and release branches in git include a pre-built copy of the ``configure`` script and may be built using: ``` tar zxvf openssh-X.YpZ.tar.gz @@ -54,7 +57,7 @@ See the [Build-time Customisation](#build-time-customisation) section below for ### Building from git -If building from git, you'll need [autoconf](https://www.gnu.org/software/autoconf/) installed to build the ``configure`` script. The following commands will check out and build portable OpenSSH from git: +If building from the git master branch, you'll need [autoconf](https://www.gnu.org/software/autoconf/) installed to build the ``configure`` script. The following commands will check out and build portable OpenSSH from git: ``` git clone https://github.com/openssh/openssh-portable # or https://anongit.mindrot.org/openssh.git diff --git a/TODO b/TODO index b76529c..e9e2d96 100644 --- a/TODO +++ b/TODO @@ -7,7 +7,7 @@ Documentation: - Install FAQ? -- General FAQ on S/Key, TIS, RSA, RSA2, DSA, etc and suggestions on when it +- General FAQ on S/Key, TIS, RSA, RSA2, etc and suggestions on when it would be best to use them. - Create a Documentation/ directory? diff --git a/addr.c b/addr.c index 0e7cb1d..2076232 100644 --- a/addr.c +++ b/addr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: addr.c,v 1.8 2024/04/02 09:29:31 deraadt Exp $ */ +/* $OpenBSD: addr.c,v 1.10 2026/03/03 09:57:25 dtucker Exp $ */ /* * Copyright (c) 2004-2008 Damien Miller @@ -33,7 +33,7 @@ #define _SA(x) ((struct sockaddr *)(x)) -int +static int addr_unicast_masklen(int af) { switch (af) { @@ -59,9 +59,9 @@ masklen_valid(int af, u_int masklen) } } -int +static int addr_xaddr_to_sa(const struct xaddr *xa, struct sockaddr *sa, socklen_t *len, - u_int16_t port) + uint16_t port) { struct sockaddr_in *in4 = (struct sockaddr_in *)sa; struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)sa; @@ -138,7 +138,7 @@ addr_sa_to_xaddr(struct sockaddr *sa, socklen_t slen, struct xaddr *xa) return 0; } -int +static int addr_invert(struct xaddr *n) { int i; @@ -193,7 +193,7 @@ addr_netmask(int af, u_int l, struct xaddr *n) } } -int +static int addr_hostmask(int af, u_int l, struct xaddr *n) { if (addr_netmask(af, l, n) == -1 || addr_invert(n) == -1) @@ -228,7 +228,7 @@ addr_and(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b) } } -int +static int addr_or(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b) { int i; @@ -283,7 +283,7 @@ addr_cmp(const struct xaddr *a, const struct xaddr *b) } } -int +static int addr_is_all0s(const struct xaddr *a) { int i; @@ -330,7 +330,7 @@ addr_increment(struct xaddr *a) * Returns 0 if host portion of address is all-zeros, * -1 if not all zeros or on failure. */ -int +static int addr_host_is_all0s(const struct xaddr *a, u_int masklen) { struct xaddr tmp_addr, tmp_mask, tmp_result; @@ -344,7 +344,7 @@ addr_host_is_all0s(const struct xaddr *a, u_int masklen) } #if 0 -int +static int addr_host_to_all0s(struct xaddr *a, u_int masklen) { struct xaddr tmp_mask; @@ -402,7 +402,8 @@ addr_pton(const char *p, struct xaddr *n) return 0; } -int +#if 0 +static int addr_sa_pton(const char *h, const char *s, struct sockaddr *sa, socklen_t slen) { struct addrinfo hints, *ai; @@ -432,6 +433,7 @@ addr_sa_pton(const char *h, const char *s, struct sockaddr *sa, socklen_t slen) freeaddrinfo(ai); return 0; } +#endif int addr_ntop(const struct xaddr *n, char *p, size_t len) diff --git a/addr.h b/addr.h index 180e9fd..a907637 100644 --- a/addr.h +++ b/addr.h @@ -27,11 +27,11 @@ struct xaddr { union { struct in_addr v4; struct in6_addr v6; - u_int8_t addr8[16]; - u_int16_t addr16[8]; - u_int32_t addr32[4]; + uint8_t addr8[16]; + uint16_t addr16[8]; + uint32_t addr32[4]; } xa; /* 128-bit address */ - u_int32_t scope_id; /* iface scope id for v6 */ + uint32_t scope_id; /* iface scope id for v6 */ #define v4 xa.v4 #define v6 xa.v6 #define addr8 xa.addr8 @@ -39,24 +39,13 @@ struct xaddr { #define addr32 xa.addr32 }; -int addr_unicast_masklen(int af); -int addr_xaddr_to_sa(const struct xaddr *xa, struct sockaddr *sa, - socklen_t *len, u_int16_t port); int addr_sa_to_xaddr(struct sockaddr *sa, socklen_t slen, struct xaddr *xa); int addr_netmask(int af, u_int l, struct xaddr *n); -int addr_hostmask(int af, u_int l, struct xaddr *n); -int addr_invert(struct xaddr *n); int addr_pton(const char *p, struct xaddr *n); -int addr_sa_pton(const char *h, const char *s, struct sockaddr *sa, - socklen_t slen); int addr_pton_cidr(const char *p, struct xaddr *n, u_int *l); int addr_ntop(const struct xaddr *n, char *p, size_t len); int addr_and(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b); -int addr_or(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b); int addr_cmp(const struct xaddr *a, const struct xaddr *b); -int addr_is_all0s(const struct xaddr *n); -int addr_host_is_all0s(const struct xaddr *n, u_int masklen); -int addr_host_to_all0s(struct xaddr *a, u_int masklen); int addr_host_to_all1s(struct xaddr *a, u_int masklen); int addr_netmatch(const struct xaddr *host, const struct xaddr *net, u_int masklen); diff --git a/addrmatch.c b/addrmatch.c index b0dc096..53a19f7 100644 --- a/addrmatch.c +++ b/addrmatch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: addrmatch.c,v 1.17 2021/04/03 06:18:40 djm Exp $ */ +/* $OpenBSD: addrmatch.c,v 1.19 2026/02/14 00:18:34 jsg Exp $ */ /* * Copyright (c) 2004-2008 Damien Miller @@ -19,11 +19,8 @@ #include "includes.h" #include -#include #include -#include -#include #include #include #include @@ -128,7 +125,7 @@ addr_match_cidr_list(const char *addr, const char *_list) /* * NB. This function is called in pre-auth with untrusted data, - * so be extra paranoid about junk reaching getaddrino (via + * so be extra paranoid about junk reaching getaddrinfo (via * addr_pton_cidr). */ diff --git a/atomicio.c b/atomicio.c index 7650733..58a9512 100644 --- a/atomicio.c +++ b/atomicio.c @@ -31,13 +31,7 @@ #include #include -#ifdef HAVE_POLL_H #include -#else -# ifdef HAVE_SYS_POLL_H -# include -# endif -#endif #include #include #include diff --git a/audit-bsm.c b/audit-bsm.c index ccfcf6f..b602913 100644 --- a/audit-bsm.c +++ b/audit-bsm.c @@ -90,7 +90,7 @@ extern void aug_save_egid(gid_t); extern void aug_save_pid(pid_t); extern void aug_save_asid(au_asid_t); extern void aug_save_tid(dev_t, unsigned int); -extern void aug_save_tid_ex(dev_t, u_int32_t *, u_int32_t); +extern void aug_save_tid_ex(dev_t, uint32_t *, uint32_t); extern int aug_save_me(void); extern int aug_save_namask(void); extern void aug_save_event(au_event_t); @@ -129,10 +129,10 @@ static AuditInfoTermID ssh_bsm_tid; * getaudit_addr() is only present on IPv6 capable machines. */ #if defined(HAVE_AUG_GET_MACHINE) || !defined(HAVE_GETAUDIT_ADDR) -extern int aug_get_machine(char *, u_int32_t *, u_int32_t *); +extern int aug_get_machine(char *, uint32_t *, uint32_t *); #else static int -aug_get_machine(char *host, u_int32_t *addr, u_int32_t *type) +aug_get_machine(char *host, uint32_t *addr, uint32_t *type) { struct addrinfo *ai; struct sockaddr_in *in4; @@ -449,7 +449,7 @@ audit_event(struct ssh *ssh, ssh_audit_event_t event) break; default: - debug("%s: unhandled event %d", __func__, event); + debug_f("unhandled event %d", event); } } #endif /* BSM */ diff --git a/audit-linux.c b/audit-linux.c index 3fcbe5c..954eabe 100644 --- a/audit-linux.c +++ b/audit-linux.c @@ -51,6 +51,8 @@ linux_audit_record_event(int uid, const char *username, const char *hostname, else return 0; /* Must prevent login */ } + if (hostname != NULL && strcmp(hostname, "UNKNOWN") == 0) + hostname = NULL; rc = audit_log_acct_message(audit_fd, AUDIT_USER_LOGIN, NULL, "login", username ? username : "(unknown)", username == NULL ? uid : -1, hostname, ip, ttyn, success); @@ -117,7 +119,7 @@ audit_event(struct ssh *ssh, ssh_audit_event_t event) ssh_remote_ipaddr(ssh), "sshd", 0); break; default: - debug("%s: unhandled event %d", __func__, event); + debug_f("unhandled event %d", event); break; } } diff --git a/auth-bsdauth.c b/auth-bsdauth.c index d124e99..d2fe51a 100644 --- a/auth-bsdauth.c +++ b/auth-bsdauth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-bsdauth.c,v 1.15 2018/07/09 21:35:50 markus Exp $ */ +/* $OpenBSD: auth-bsdauth.c,v 1.16 2026/02/06 01:24:36 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -125,14 +125,6 @@ bsdauth_free_ctx(void *ctx) } } -KbdintDevice bsdauth_device = { - "bsdauth", - bsdauth_init_ctx, - bsdauth_query, - bsdauth_respond, - bsdauth_free_ctx -}; - KbdintDevice mm_bsdauth_device = { "bsdauth", bsdauth_init_ctx, diff --git a/auth-krb5.c b/auth-krb5.c index c99e4e4..3c6dc06 100644 --- a/auth-krb5.c +++ b/auth-krb5.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-krb5.c,v 1.24 2021/04/03 06:18:40 djm Exp $ */ +/* $OpenBSD: auth-krb5.c,v 1.26 2026/02/08 19:54:31 dtucker Exp $ */ /* * Kerberos v5 authentication and ticket-passing routines. * diff --git a/auth-options.c b/auth-options.c index c89b1ee..e15f600 100644 --- a/auth-options.c +++ b/auth-options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-options.c,v 1.101 2023/07/14 07:44:21 dtucker Exp $ */ +/* $OpenBSD: auth-options.c,v 1.102 2025/09/15 04:38:00 djm Exp $ */ /* * Copyright (c) 2018 Damien Miller * @@ -18,21 +18,18 @@ #include "includes.h" #include +#include #include #include #include #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include #include -#include "openbsd-compat/sys-queue.h" - #include "xmalloc.h" #include "ssherr.h" #include "log.h" @@ -157,6 +154,7 @@ cert_option_list(struct sshauthopt *opts, struct sshbuf *oblob, if (addr_match_cidr_list(NULL, allowed) == -1) { error("Certificate source-address " "contents invalid"); + free(allowed); goto out; } opts->required_from_host_cert = allowed; diff --git a/auth-pam.c b/auth-pam.c index 13c0a79..29607e0 100644 --- a/auth-pam.c +++ b/auth-pam.c @@ -95,7 +95,6 @@ #include "servconf.h" #include "ssh2.h" #include "auth-options.h" -#include "misc.h" #ifdef GSSAPI #include "ssh-gss.h" #endif @@ -132,11 +131,17 @@ typedef pid_t sp_pthread_t; #define pthread_join fake_pthread_join #endif +typedef int SshPamDone; +#define SshPamError -1 +#define SshPamNone 0 +#define SshPamAuthenticated 1 +#define SshPamAgain 2 + struct pam_ctxt { sp_pthread_t pam_thread; int pam_psock; int pam_csock; - int pam_done; + SshPamDone pam_done; }; static void sshpam_free_ctx(void *); @@ -158,7 +163,7 @@ sshpam_sigchld_handler(int sig) return; /* handler called after PAM cleanup, shouldn't happen */ if (waitpid(cleanup_ctxt->pam_thread, &sshpam_thread_status, WNOHANG) <= 0) { - /* PAM thread has not exitted, privsep slave must have */ + /* PAM thread has not exited, privsep slave must have */ kill(cleanup_ctxt->pam_thread, SIGTERM); while (waitpid(cleanup_ctxt->pam_thread, &sshpam_thread_status, 0) == -1) { @@ -229,7 +234,7 @@ pthread_join(sp_pthread_t thread, void **value) while (waitpid(thread, &status, 0) == -1) { if (errno == EINTR) continue; - fatal("%s: waitpid: %s", __func__, strerror(errno)); + fatal_f("waitpid: %s", strerror(errno)); } return (status); } @@ -237,6 +242,7 @@ pthread_join(sp_pthread_t thread, void **value) static pam_handle_t *sshpam_handle = NULL; +static char *sshpam_initial_user; static int sshpam_err = 0; static int sshpam_authenticated = 0; static int sshpam_session_open = 0; @@ -271,40 +277,15 @@ pam_putenv(pam_handle_t *pamh, const char *name_value) } #endif /* HAVE_PAM_PUTENV */ -/* - * Some platforms, notably Solaris, do not enforce password complexity - * rules during pam_chauthtok() if the real uid of the calling process - * is 0, on the assumption that it's being called by "passwd" run by root. - * This wraps pam_chauthtok and sets/restore the real uid so PAM will do - * the right thing. - */ -#ifdef SSHPAM_CHAUTHTOK_NEEDS_RUID -static int -sshpam_chauthtok_ruid(pam_handle_t *pamh, int flags) -{ - int result; - - if (sshpam_authctxt == NULL) - fatal("PAM: sshpam_authctxt not initialized"); - if (setreuid(sshpam_authctxt->pw->pw_uid, -1) == -1) - fatal("%s: setreuid failed: %s", __func__, strerror(errno)); - result = pam_chauthtok(pamh, flags); - if (setreuid(0, -1) == -1) - fatal("%s: setreuid failed: %s", __func__, strerror(errno)); - return result; -} -# define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) -#endif - static void sshpam_password_change_required(int reqd) { extern struct sshauthopt *auth_opts; static int saved_port, saved_agent, saved_x11; - debug3("%s %d", __func__, reqd); + debug3_f("reqd=%d", reqd); if (sshpam_authctxt == NULL) - fatal("%s: PAM authctxt not initialized", __func__); + fatal_f("PAM authctxt not initialized"); sshpam_authctxt->force_pwchange = reqd; if (reqd) { saved_port = auth_opts->permit_port_forwarding_flag; @@ -331,22 +312,22 @@ import_environments(struct sshbuf *b) u_int n, i, num_env; int r; - debug3("PAM: %s entering", __func__); + debug3_f("entering"); #ifndef UNSUPPORTED_POSIX_THREADS_HACK /* Import variables set by do_pam_account */ if ((r = sshbuf_get_u32(b, &n)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); if (n > INT_MAX) - fatal("%s: invalid PAM account status %u", __func__, n); + fatal_f("invalid PAM account status %u", n); sshpam_account_status = (int)n; if ((r = sshbuf_get_u32(b, &n)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); sshpam_password_change_required(n != 0); /* Import environment from subprocess */ if ((r = sshbuf_get_u32(b, &num_env)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); if (num_env > 1024) { fatal_f("received %u environment variables, expected <= 1024", num_env); @@ -355,13 +336,13 @@ import_environments(struct sshbuf *b) debug3("PAM: num env strings %u", num_env); for(i = 0; i < num_env; i++) { if ((r = sshbuf_get_cstring(b, &(sshpam_env[i]), NULL)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); } sshpam_env[num_env] = NULL; /* Import PAM environment from subprocess */ if ((r = sshbuf_get_u32(b, &num_env)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); if (num_env > 1024) { fatal_f("received %u PAM env variables, expected <= 1024", num_env); @@ -369,7 +350,7 @@ import_environments(struct sshbuf *b) debug("PAM: num PAM env strings %u", num_env); for (i = 0; i < num_env; i++) { if ((r = sshbuf_get_cstring(b, &env, NULL)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); /* Errors are not fatal here */ if ((r = pam_putenv(sshpam_handle, env)) != PAM_SUCCESS) { error("PAM: pam_putenv: %s", @@ -378,7 +359,7 @@ import_environments(struct sshbuf *b) /* * XXX this possibly leaks env because it is not documented * what pam_putenv() does with it. Does it copy it? Does it - * take ownweship? We don't know, so it's safest just to leak. + * take ownership? We don't know, so it's safest just to leak. */ } #endif @@ -397,7 +378,7 @@ sshpam_thread_conv(int n, sshpam_const struct pam_message **msg, int r, i; u_char status; - debug3("PAM: %s entering, %d messages", __func__, n); + debug3_f("PAM: entering, %d messages", n); *resp = NULL; if (data == NULL) { @@ -441,6 +422,9 @@ sshpam_thread_conv(int n, sshpam_const struct pam_message **msg, break; case PAM_ERROR_MSG: case PAM_TEXT_INFO: + debug3("PAM: Got message of type %d: %s", + PAM_MSG_MEMBER(msg, i, msg_style), + PAM_MSG_MEMBER(msg, i, msg)); if ((r = sshbuf_put_cstring(buffer, PAM_MSG_MEMBER(msg, i, msg))) != 0) fatal("%s: buffer error: %s", @@ -467,6 +451,34 @@ sshpam_thread_conv(int n, sshpam_const struct pam_message **msg, return (PAM_CONV_ERR); } +static int +check_pam_user(Authctxt *authctxt) +{ + const char *pam_user; + + if (authctxt == NULL || authctxt->pw == NULL || + authctxt->pw->pw_name == NULL) + fatal_f("PAM authctxt user not initialized"); + + if ((sshpam_err = pam_get_item(sshpam_handle, PAM_USER, + (sshpam_const void **) &pam_user)) != PAM_SUCCESS) + return sshpam_err; + + if (pam_user == NULL) { + debug("PAM error: PAM_USER is NULL"); + return PAM_USER_UNKNOWN; + } + + if (sshpam_initial_user == NULL) + fatal_f("internal error: sshpam_initial_user NULL"); + if (strcmp(sshpam_initial_user, pam_user) != 0) { + error_f("PAM user \"%s\" does not match previous \"%s\"", + pam_user, sshpam_initial_user); + return PAM_USER_UNKNOWN; + } + return PAM_SUCCESS; +} + /* * Authentication thread. */ @@ -507,10 +519,10 @@ sshpam_thread(void *ctxtp) sshpam_conv.appdata_ptr = ctxt; if (sshpam_authctxt == NULL) - fatal("%s: PAM authctxt not initialized", __func__); + fatal_f("PAM authctxt not initialized"); if ((buffer = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, (const void *)&sshpam_conv); @@ -521,6 +533,8 @@ sshpam_thread(void *ctxtp) sshpam_set_maxtries_reached(1); if (sshpam_err != PAM_SUCCESS) goto auth_fail; + if ((sshpam_err = check_pam_user(sshpam_authctxt)) != PAM_SUCCESS) + goto auth_fail; if (!do_pam_account()) { sshpam_err = PAM_ACCT_EXPIRED; @@ -535,38 +549,38 @@ sshpam_thread(void *ctxtp) } if ((r = sshbuf_put_cstring(buffer, "OK")) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); #ifndef UNSUPPORTED_POSIX_THREADS_HACK /* Export variables set by do_pam_account */ if ((r = sshbuf_put_u32(buffer, sshpam_account_status)) != 0 || (r = sshbuf_put_u32(buffer, sshpam_authctxt->force_pwchange)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); /* Export any environment strings set in child */ for (i = 0; environ[i] != NULL; i++) { /* Count */ if (i > INT_MAX) - fatal("%s: too many environment strings", __func__); + fatal_f("too many environment strings"); } if ((r = sshbuf_put_u32(buffer, i)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); for (i = 0; environ[i] != NULL; i++) { if ((r = sshbuf_put_cstring(buffer, environ[i])) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); } /* Export any environment strings set by PAM in child */ env_from_pam = pam_getenvlist(sshpam_handle); for (i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++) { /* Count */ if (i > INT_MAX) - fatal("%s: too many PAM environment strings", __func__); + fatal_f("too many PAM environment strings"); } if ((r = sshbuf_put_u32(buffer, i)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); for (i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++) { if ((r = sshbuf_put_cstring(buffer, env_from_pam[i])) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); } #endif /* UNSUPPORTED_POSIX_THREADS_HACK */ @@ -578,7 +592,7 @@ sshpam_thread(void *ctxtp) auth_fail: if ((r = sshbuf_put_cstring(buffer, pam_strerror(sshpam_handle, sshpam_err))) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); /* XXX - can't do much about an error here */ if (sshpam_err == PAM_ACCT_EXPIRED) ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, buffer); @@ -597,7 +611,7 @@ sshpam_thread_cleanup(void) { struct pam_ctxt *ctxt = cleanup_ctxt; - debug3("PAM: %s entering", __func__); + debug3_f("entering"); if (ctxt != NULL && ctxt->pam_thread != 0) { pthread_cancel(ctxt->pam_thread); pthread_join(ctxt->pam_thread, NULL); @@ -612,7 +626,7 @@ static int sshpam_null_conv(int n, sshpam_const struct pam_message **msg, struct pam_response **resp, void *data) { - debug3("PAM: %s entering, %d messages", __func__, n); + debug3_f("PAM: entering, %d messages", n); return (PAM_CONV_ERR); } @@ -625,7 +639,7 @@ sshpam_store_conv(int n, sshpam_const struct pam_message **msg, struct pam_response *reply; int r, i; - debug3("PAM: %s called with %d messages", __func__, n); + debug3_f("PAM: called with %d messages", n); *resp = NULL; if (n <= 0 || n > PAM_MAX_NUM_MSG) @@ -681,13 +695,14 @@ sshpam_cleanup(void) sshpam_authenticated = 0; pam_end(sshpam_handle, sshpam_err); sshpam_handle = NULL; + free(sshpam_initial_user); + sshpam_initial_user = NULL; } static int sshpam_init(struct ssh *ssh, Authctxt *authctxt) { - const char *pam_user, *user = authctxt->user; - const char **ptr_pam_user = &pam_user; + const char *user = authctxt->user; int r; if (options.pam_service_name == NULL) @@ -698,25 +713,19 @@ sshpam_init(struct ssh *ssh, Authctxt *authctxt) fatal("Username too long from %s port %d", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); #endif - if (sshpam_handle == NULL) { - if (ssh == NULL) { - fatal("%s: called initially with no " - "packet context", __func__); - } - } + if (sshpam_handle == NULL && ssh == NULL) + fatal("%s: called initially with no packet context", __func__); if (sshpam_handle != NULL) { /* We already have a PAM context; check if the user matches */ - sshpam_err = pam_get_item(sshpam_handle, - PAM_USER, (sshpam_const void **)ptr_pam_user); - if (sshpam_err == PAM_SUCCESS && strcmp(user, pam_user) == 0) - return (0); - pam_end(sshpam_handle, sshpam_err); - sshpam_handle = NULL; + if ((sshpam_err = check_pam_user(authctxt)) != PAM_SUCCESS) + fatal("PAM user mismatch"); + return 0; } debug("PAM: initializing for \"%s\" with service \"%s\"", user, options.pam_service_name); sshpam_err = pam_start(options.pam_service_name, user, &store_conv, &sshpam_handle); + sshpam_initial_user = xstrdup(user); sshpam_authctxt = authctxt; if (sshpam_err != PAM_SUCCESS) { @@ -735,7 +744,7 @@ sshpam_init(struct ssh *ssh, Authctxt *authctxt) sshpam_laddr = get_local_ipaddr( ssh_packet_get_connection_in(ssh)); } - if (sshpam_rhost != NULL) { + if (sshpam_rhost != NULL && strcmp(sshpam_rhost, "UNKNOWN") != 0) { debug("PAM: setting PAM_RHOST to \"%s\"", sshpam_rhost); sshpam_err = pam_set_item(sshpam_handle, PAM_RHOST, sshpam_rhost); @@ -788,7 +797,7 @@ expose_authinfo(const char *caller) auth_info = xstrdup(""); else if ((auth_info = sshbuf_dup_string( sshpam_authctxt->session_info)) == NULL) - fatal("%s: sshbuf_dup_string failed", __func__); + fatal_f("sshbuf_dup_string failed"); debug2("%s: auth information in SSH_AUTH_INFO_0", caller); do_pam_putenv("SSH_AUTH_INFO_0", auth_info); @@ -801,7 +810,7 @@ sshpam_init_ctx(Authctxt *authctxt) struct pam_ctxt *ctxt; int result, socks[2]; - debug3("PAM: %s entering", __func__); + debug3_f("entering"); /* * Refuse to start if we don't have PAM enabled or do_pam_account * has previously failed. @@ -845,50 +854,44 @@ sshpam_query(void *ctx, char **name, char **info, { struct sshbuf *buffer; struct pam_ctxt *ctxt = ctx; - size_t plen; u_char type; char *msg; - size_t len, mlen, nmesg = 0; + size_t mlen, nmesg = 0; int r; - debug3("PAM: %s entering", __func__); + debug3_f("entering"); if ((buffer = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); *name = xstrdup(""); *info = xstrdup(""); - *prompts = xmalloc(sizeof(char *)); - **prompts = NULL; - plen = 0; - *echo_on = xmalloc(sizeof(u_int)); + *prompts = NULL; + *num = 0; + ctxt->pam_done = SshPamNone; + while (ssh_msg_recv(ctxt->pam_psock, buffer) == 0) { if (++nmesg > PAM_MAX_NUM_MSG) fatal_f("too many query messages"); if ((r = sshbuf_get_u8(buffer, &type)) != 0 || (r = sshbuf_get_cstring(buffer, &msg, &mlen)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); switch (type) { case PAM_PROMPT_ECHO_ON: case PAM_PROMPT_ECHO_OFF: + *prompts = xcalloc(1, sizeof(char *)); + *echo_on = xcalloc(1, sizeof(u_int)); + (*prompts)[0] = msg; /* transfer ownership */ + (*echo_on)[0] = (type == PAM_PROMPT_ECHO_ON); *num = 1; - len = plen + mlen + 1; - **prompts = xreallocarray(**prompts, 1, len); - strlcpy(**prompts + plen, msg, len - plen); - plen += mlen; - **echo_on = (type == PAM_PROMPT_ECHO_ON); - free(msg); sshbuf_free(buffer); return (0); case PAM_ERROR_MSG: case PAM_TEXT_INFO: - /* accumulate messages */ - len = plen + mlen + 2; - **prompts = xreallocarray(**prompts, 1, len); - strlcpy(**prompts + plen, msg, len - plen); - plen += mlen; - strlcat(**prompts + plen, "\n", len - plen); - plen++; - free(msg); - break; + free(*info); + *info = msg; /* transfer ownership */ + msg = NULL; + ctxt->pam_done = SshPamAgain; + sshbuf_free(buffer); + return (0); case PAM_ACCT_EXPIRED: case PAM_MAXTRIES: if (type == PAM_ACCT_EXPIRED) @@ -898,29 +901,8 @@ sshpam_query(void *ctx, char **name, char **info, /* FALLTHROUGH */ case PAM_AUTH_ERR: debug3("PAM: %s", pam_strerror(sshpam_handle, type)); - if (**prompts != NULL && strlen(**prompts) != 0) { - free(*info); - *info = **prompts; - **prompts = NULL; - *num = 0; - **echo_on = 0; - ctxt->pam_done = -1; - free(msg); - sshbuf_free(buffer); - return 0; - } /* FALLTHROUGH */ case PAM_SUCCESS: - if (**prompts != NULL) { - /* drain any accumulated messages */ - debug("PAM: %s", **prompts); - if ((r = sshbuf_put(loginmsg, **prompts, - strlen(**prompts))) != 0) - fatal("%s: buffer error: %s", - __func__, ssh_err(r)); - free(**prompts); - **prompts = NULL; - } if (type == PAM_SUCCESS) { if (!sshpam_authctxt->valid || (sshpam_authctxt->pw->pw_uid == 0 && @@ -929,9 +911,7 @@ sshpam_query(void *ctx, char **name, char **info, "succeeded when it should have " "failed"); import_environments(buffer); - *num = 0; - **echo_on = 0; - ctxt->pam_done = 1; + ctxt->pam_done = SshPamAuthenticated; free(msg); sshbuf_free(buffer); return (0); @@ -941,10 +921,8 @@ sshpam_query(void *ctx, char **name, char **info, sshpam_authctxt->user, sshpam_rhost); /* FALLTHROUGH */ default: - *num = 0; - **echo_on = 0; free(msg); - ctxt->pam_done = -1; + ctxt->pam_done = SshPamError; sshbuf_free(buffer); return (-1); } @@ -966,7 +944,7 @@ fake_password(const char *wire_password) size_t i, l = wire_password != NULL ? strlen(wire_password) : 0; if (l >= INT_MAX) - fatal("%s: password length too long: %zu", __func__, l); + fatal_f("password length too long: %zu", l); ret = malloc(l + 1); if (ret == NULL) @@ -977,7 +955,6 @@ fake_password(const char *wire_password) return ret; } -/* XXX - see also comment in auth-chall.c:verify_response */ static int sshpam_respond(void *ctx, u_int num, char **resp) { @@ -986,13 +963,15 @@ sshpam_respond(void *ctx, u_int num, char **resp) char *fake; int r; - debug2("PAM: %s entering, %u responses", __func__, num); + debug2_f("PAM: entering, %u responses", num); switch (ctxt->pam_done) { - case 1: + case SshPamAuthenticated: sshpam_authenticated = 1; return (0); - case 0: + case SshPamNone: break; + case SshPamAgain: + return 1; /* KbdintResultAgain */ default: return (-1); } @@ -1001,16 +980,16 @@ sshpam_respond(void *ctx, u_int num, char **resp) return (-1); } if ((buffer = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); if (sshpam_authctxt->valid && (sshpam_authctxt->pw->pw_uid != 0 || options.permit_root_login == PERMIT_YES)) { if ((r = sshbuf_put_cstring(buffer, *resp)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); } else { fake = fake_password(*resp); if ((r = sshbuf_put_cstring(buffer, fake)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); free(fake); } if (ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, buffer) == -1) { @@ -1026,7 +1005,7 @@ sshpam_free_ctx(void *ctxtp) { struct pam_ctxt *ctxt = ctxtp; - debug3("PAM: %s entering", __func__); + debug3_f("entering"); sshpam_thread_cleanup(); free(ctxt); /* @@ -1037,6 +1016,14 @@ sshpam_free_ctx(void *ctxtp) */ } +int +sshpam_priv_kbdint_authdone(void *ctxtp) +{ + struct pam_ctxt *ctxt = ctxtp; + + return ctxt->pam_done == SshPamAuthenticated; +} + KbdintDevice sshpam_device = { "pam", sshpam_init_ctx, @@ -1078,7 +1065,7 @@ finish_pam(void) u_int do_pam_account(void) { - debug("%s: called", __func__); + debug_f("called"); if (sshpam_account_status != -1) return (sshpam_account_status); @@ -1122,86 +1109,6 @@ do_pam_setcred(void) pam_strerror(sshpam_handle, sshpam_err)); } -#if 0 -static int -sshpam_tty_conv(int n, sshpam_const struct pam_message **msg, - struct pam_response **resp, void *data) -{ - char input[PAM_MAX_MSG_SIZE]; - struct pam_response *reply; - int i; - - debug3("PAM: %s called with %d messages", __func__, n); - - *resp = NULL; - - if (n <= 0 || n > PAM_MAX_NUM_MSG || !isatty(STDIN_FILENO)) - return (PAM_CONV_ERR); - - if ((reply = calloc(n, sizeof(*reply))) == NULL) - return (PAM_CONV_ERR); - - for (i = 0; i < n; ++i) { - switch (PAM_MSG_MEMBER(msg, i, msg_style)) { - case PAM_PROMPT_ECHO_OFF: - reply[i].resp = - read_passphrase(PAM_MSG_MEMBER(msg, i, msg), - RP_ALLOW_STDIN); - reply[i].resp_retcode = PAM_SUCCESS; - break; - case PAM_PROMPT_ECHO_ON: - fprintf(stderr, "%s\n", PAM_MSG_MEMBER(msg, i, msg)); - if (fgets(input, sizeof input, stdin) == NULL) - input[0] = '\0'; - if ((reply[i].resp = strdup(input)) == NULL) - goto fail; - reply[i].resp_retcode = PAM_SUCCESS; - break; - case PAM_ERROR_MSG: - case PAM_TEXT_INFO: - fprintf(stderr, "%s\n", PAM_MSG_MEMBER(msg, i, msg)); - reply[i].resp_retcode = PAM_SUCCESS; - break; - default: - goto fail; - } - } - *resp = reply; - return (PAM_SUCCESS); - - fail: - for(i = 0; i < n; i++) { - free(reply[i].resp); - } - free(reply); - return (PAM_CONV_ERR); -} - -static struct pam_conv tty_conv = { sshpam_tty_conv, NULL }; -#endif - -/* - * XXX this should be done in the authentication phase, but ssh1 doesn't - * support that - */ -void -do_pam_chauthtok(void) -{ - fatal("Password expired"); -#if 0 - sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, - (const void *)&tty_conv); - if (sshpam_err != PAM_SUCCESS) - fatal("PAM: failed to set PAM_CONV: %s", - pam_strerror(sshpam_handle, sshpam_err)); - debug("PAM: changing password"); - sshpam_err = pam_chauthtok(sshpam_handle, PAM_CHANGE_EXPIRED_AUTHTOK); - if (sshpam_err != PAM_SUCCESS) - fatal("PAM: pam_chauthtok(): %s", - pam_strerror(sshpam_handle, sshpam_err)); -#endif -} - void do_pam_session(struct ssh *ssh) { @@ -1292,7 +1199,7 @@ sshpam_passwd_conv(int n, sshpam_const struct pam_message **msg, int r, i; size_t len; - debug3("PAM: %s called with %d messages", __func__, n); + debug3_f("PAM: called with %d messages", n); *resp = NULL; @@ -1378,6 +1285,8 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password) sshpam_err = pam_authenticate(sshpam_handle, flags); sshpam_password = NULL; free(fake); + if (sshpam_err == PAM_SUCCESS) + sshpam_err = check_pam_user(authctxt); if (sshpam_err == PAM_MAXTRIES) sshpam_set_maxtries_reached(1); if (sshpam_err == PAM_SUCCESS && authctxt->valid) { diff --git a/auth-pam.h b/auth-pam.h index 8d801c6..4913367 100644 --- a/auth-pam.h +++ b/auth-pam.h @@ -32,7 +32,6 @@ void finish_pam(void); u_int do_pam_account(void); void do_pam_session(struct ssh *); void do_pam_setcred(void); -void do_pam_chauthtok(void); int do_pam_putenv(char *, char *); char ** fetch_pam_environment(void); char ** fetch_pam_child_environment(void); @@ -43,5 +42,6 @@ int sshpam_auth_passwd(Authctxt *, const char *); int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); int is_pam_session_open(void); +int sshpam_priv_kbdint_authdone(void *ctxtp); #endif /* USE_PAM */ diff --git a/auth-passwd.c b/auth-passwd.c index 347d91e..a9d7688 100644 --- a/auth-passwd.c +++ b/auth-passwd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-passwd.c,v 1.48 2020/10/18 11:32:01 djm Exp $ */ +/* $OpenBSD: auth-passwd.c,v 1.49 2025/05/08 17:32:53 tedu Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -133,7 +133,7 @@ static void warn_expiry(Authctxt *authctxt, auth_session_t *as) { int r; - quad_t pwtimeleft, actimeleft, daysleft, pwwarntime, acwarntime; + int64_t pwtimeleft, actimeleft, daysleft, pwwarntime, acwarntime; pwwarntime = acwarntime = TWO_WEEKS; diff --git a/auth-rhosts.c b/auth-rhosts.c index d5d2c7a..031186f 100644 --- a/auth-rhosts.c +++ b/auth-rhosts.c @@ -21,9 +21,7 @@ #include #include -#ifdef HAVE_NETGROUP_H -# include -#endif +#include #include #include #include diff --git a/auth-shadow.c b/auth-shadow.c index b1e3aa9..81b31b5 100644 --- a/auth-shadow.c +++ b/auth-shadow.c @@ -74,7 +74,7 @@ auth_shadow_acctexpired(struct spwd *spw) if ((r = sshbuf_putf(loginmsg, "Your account will expire in %lld day%s.\n", daysleft, daysleft == 1 ? "" : "s")) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); } return 0; @@ -133,7 +133,7 @@ auth_shadow_pwexpired(Authctxt *ctxt) if ((r = sshbuf_putf(loginmsg, "Your password will expire in %d day%s.\n", daysleft, daysleft == 1 ? "" : "s")) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); } return 0; diff --git a/auth.c b/auth.c index 9a6e5a3..a0217a8 100644 --- a/auth.c +++ b/auth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.c,v 1.162 2024/09/15 01:18:26 djm Exp $ */ +/* $OpenBSD: auth.c,v 1.164 2026/02/11 22:57:16 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -35,9 +35,7 @@ #include #include #include -#ifdef HAVE_PATHS_H -# include -#endif +#include #include #ifdef HAVE_LOGIN_H #include @@ -100,8 +98,8 @@ allowed_user(struct ssh *ssh, struct passwd * pw) { struct stat st; const char *hostname = NULL, *ipaddr = NULL; - u_int i; int r; + u_int i; /* Shouldn't be called if pw is NULL, but better safe than sorry... */ if (!pw || !pw->pw_name) @@ -547,9 +545,10 @@ int auth_key_is_revoked(struct sshkey *key) { char *fp = NULL; + u_int i; int r; - if (options.revoked_keys_file == NULL) + if (options.num_revoked_keys_files == 0) return 0; if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { @@ -558,19 +557,22 @@ auth_key_is_revoked(struct sshkey *key) goto out; } - r = sshkey_check_revoked(key, options.revoked_keys_file); - switch (r) { - case 0: - break; /* not revoked */ - case SSH_ERR_KEY_REVOKED: - error("Authentication key %s %s revoked by file %s", - sshkey_type(key), fp, options.revoked_keys_file); - goto out; - default: - error_r(r, "Error checking authentication key %s %s in " - "revoked keys file %s", sshkey_type(key), fp, - options.revoked_keys_file); - goto out; + for (i = 0; i < options.num_revoked_keys_files; i++) { + r = sshkey_check_revoked(key, options.revoked_keys_files[i]); + switch (r) { + case 0: + break; /* not revoked */ + case SSH_ERR_KEY_REVOKED: + error("Authentication key %s %s revoked by file %s", + sshkey_type(key), fp, + options.revoked_keys_files[i]); + goto out; + default: + error_r(r, "Error checking authentication key %s %s in " + "revoked keys file %s", sshkey_type(key), fp, + options.revoked_keys_files[i]); + goto out; + } } /* Success */ @@ -758,6 +760,7 @@ auth_activate_options(struct ssh *ssh, struct sshauthopt *opts) error("Inconsistent authentication options: %s", emsg); return -1; } + sshauthopt_free(old); return 0; } diff --git a/auth.h b/auth.h index 98bb23d..634a84a 100644 --- a/auth.h +++ b/auth.h @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.h,v 1.108 2024/05/17 06:42:04 jsg Exp $ */ +/* $OpenBSD: auth.h,v 1.109 2026/02/06 01:24:36 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -182,8 +182,6 @@ int auth2_update_methods_lists(Authctxt *, const char *, const char *); int auth2_setup_methods_lists(Authctxt *); int auth2_method_allowed(Authctxt *, const char *, const char *); -void privsep_challenge_enable(void); - int auth2_challenge(struct ssh *, char *); void auth2_challenge_stop(struct ssh *); int bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **); diff --git a/auth2-chall.c b/auth2-chall.c index 021df82..f388907 100644 --- a/auth2-chall.c +++ b/auth2-chall.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-chall.c,v 1.54 2020/10/18 11:32:01 djm Exp $ */ +/* $OpenBSD: auth2-chall.c,v 1.60 2026/03/03 09:57:25 dtucker Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2001 Per Allansson. All rights reserved. @@ -51,22 +51,22 @@ extern ServerOptions options; static int auth2_challenge_start(struct ssh *); static int send_userauth_info_request(struct ssh *); -static int input_userauth_info_response(int, u_int32_t, struct ssh *); +static int input_userauth_info_response(int, uint32_t, struct ssh *); #ifdef BSD_AUTH -extern KbdintDevice bsdauth_device; +extern KbdintDevice mm_bsdauth_device; #else #ifdef USE_PAM -extern KbdintDevice sshpam_device; +extern KbdintDevice mm_sshpam_device; #endif #endif KbdintDevice *devices[] = { #ifdef BSD_AUTH - &bsdauth_device, + &mm_bsdauth_device, #else #ifdef USE_PAM - &sshpam_device, + &mm_sshpam_device, #endif #endif NULL @@ -154,7 +154,7 @@ kbdint_next_device(Authctxt *authctxt, KbdintAuthctxt *kbdintctxt) { size_t len; char *t; - int i; + size_t i; if (kbdintctxt->device) kbdint_reset_device(kbdintctxt); @@ -165,11 +165,15 @@ kbdint_next_device(Authctxt *authctxt, KbdintAuthctxt *kbdintctxt) if (len == 0) break; for (i = 0; devices[i]; i++) { + if (i >= sizeof(kbdintctxt->devices_done) * 8 || + i >= sizeof(devices) / sizeof(devices[0])) + fatal_f("internal error: too many devices"); if ((kbdintctxt->devices_done & (1 << i)) != 0 || !auth2_method_allowed(authctxt, "keyboard-interactive", devices[i]->name)) continue; - if (strncmp(kbdintctxt->devices, devices[i]->name, + if (strlen(devices[i]->name) == len && + memcmp(kbdintctxt->devices, devices[i]->name, len) == 0) { kbdintctxt->device = devices[i]; kbdintctxt->devices_done |= 1 << i; @@ -287,7 +291,7 @@ send_userauth_info_request(struct ssh *ssh) } static int -input_userauth_info_response(int type, u_int32_t seq, struct ssh *ssh) +input_userauth_info_response(int type, uint32_t seq, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; KbdintAuthctxt *kbdintctxt; @@ -358,25 +362,3 @@ input_userauth_info_response(int type, u_int32_t seq, struct ssh *ssh) devicename); return 0; } - -void -privsep_challenge_enable(void) -{ -#if defined(BSD_AUTH) || defined(USE_PAM) - int n = 0; -#endif -#ifdef BSD_AUTH - extern KbdintDevice mm_bsdauth_device; -#endif -#ifdef USE_PAM - extern KbdintDevice mm_sshpam_device; -#endif - -#ifdef BSD_AUTH - devices[n++] = &mm_bsdauth_device; -#else -#ifdef USE_PAM - devices[n++] = &mm_sshpam_device; -#endif -#endif -} diff --git a/auth2-gss.c b/auth2-gss.c index 75eb4e3..0535485 100644 --- a/auth2-gss.c +++ b/auth2-gss.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-gss.c,v 1.36 2024/05/17 04:42:13 djm Exp $ */ +/* $OpenBSD: auth2-gss.c,v 1.39 2026/03/03 09:57:25 dtucker Exp $ */ /* * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -53,10 +53,10 @@ extern ServerOptions options; extern struct authmethod_cfg methodcfg_gssapi; -static int input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh); -static int input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh); -static int input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh); -static int input_gssapi_errtok(int, u_int32_t, struct ssh *); +static int input_gssapi_token(int type, uint32_t plen, struct ssh *ssh); +static int input_gssapi_mic(int type, uint32_t plen, struct ssh *ssh); +static int input_gssapi_exchange_complete(int type, uint32_t plen, struct ssh *ssh); +static int input_gssapi_errtok(int, uint32_t, struct ssh *); /* * We only support those mechanisms that we know about (ie ones that we know @@ -143,7 +143,7 @@ userauth_gssapi(struct ssh *ssh, const char *method) } static int -input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh) +input_gssapi_token(int type, uint32_t plen, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; Gssctxt *gssctxt; @@ -207,7 +207,7 @@ input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh) } static int -input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh) +input_gssapi_errtok(int type, uint32_t plen, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; Gssctxt *gssctxt; @@ -251,7 +251,7 @@ input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh) */ static int -input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh) +input_gssapi_exchange_complete(int type, uint32_t plen, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; int r, authenticated; @@ -279,7 +279,7 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh) } static int -input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) +input_gssapi_mic(int type, uint32_t plen, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; Gssctxt *gssctxt; @@ -328,5 +328,4 @@ Authmethod method_gssapi = { &methodcfg_gssapi, userauth_gssapi, }; - -#endif /* GSSAPI */ +#endif diff --git a/auth2-hostbased.c b/auth2-hostbased.c index eb21479..8a1acde 100644 --- a/auth2-hostbased.c +++ b/auth2-hostbased.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-hostbased.c,v 1.53 2024/05/17 00:30:23 djm Exp $ */ +/* $OpenBSD: auth2-hostbased.c,v 1.57 2026/04/02 07:48:13 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -96,9 +96,10 @@ userauth_hostbased(struct ssh *ssh, const char *method) error_f("cannot decode key: %s", pkalg); goto done; } - if (key->type != pktype) { - error_f("type mismatch for decoded key " - "(received %d, expected %d)", key->type, pktype); + if (key->type != pktype || (sshkey_type_plain(pktype) == KEY_ECDSA && + sshkey_ecdsa_nid_from_name(pkalg) != key->ecdsa_nid)) { + error_f("key type mismatch for decoded key " + "(received %s, expected %s)", sshkey_ssh_name(key), pkalg); goto done; } if (match_pattern_list(pkalg, options.hostbased_accepted_algos, 0) != 1) { @@ -211,10 +212,19 @@ hostbased_key_allowed(struct ssh *ssh, struct passwd *pw, } debug2_f("access allowed by auth_rhosts2"); - if (sshkey_is_cert(key) && - sshkey_cert_check_authority_now(key, 1, 0, 0, lookup, &reason)) { - error("%s", reason); - auth_debug_add("%s", reason); + if (sshkey_is_cert(key) && sshkey_cert_check_host(key, lookup, + options.ca_sign_algorithms, &reason) != 0) { + if ((fp = sshkey_fingerprint(key->cert->signature_key, + options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) + fatal_f("sshkey_fingerprint fail"); + error("Refusing certificate ID \"%s\" serial=%llu signed by " + "%s CA %s: %s", key->cert->key_id, + (unsigned long long)key->cert->serial, + sshkey_type(key->cert->signature_key), fp, reason); + auth_debug_add("Refused Certificate ID \"%s\" serial=%llu: %s", + key->cert->key_id, (unsigned long long)key->cert->serial, + reason); + free(fp); return 0; } diff --git a/auth2-none.c b/auth2-none.c index c3ed53f..900cae9 100644 --- a/auth2-none.c +++ b/auth2-none.c @@ -26,16 +26,9 @@ #include "includes.h" #include -#include -#include - -#include -#include -#include #include #include -#include "atomicio.h" #include "xmalloc.h" #include "sshkey.h" #include "hostfile.h" diff --git a/auth2-pubkey.c b/auth2-pubkey.c index 7580db7..e446ef4 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-pubkey.c,v 1.120 2024/05/17 00:30:23 djm Exp $ */ +/* $OpenBSD: auth2-pubkey.c,v 1.126 2026/04/02 07:48:13 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -30,10 +30,9 @@ #include #include -#ifdef HAVE_PATHS_H -# include -#endif +#include #include +#include #include #include #include @@ -149,9 +148,10 @@ userauth_pubkey(struct ssh *ssh, const char *method) error_f("cannot decode key: %s", pkalg); goto done; } - if (key->type != pktype) { - error_f("type mismatch for decoded key " - "(received %d, expected %d)", key->type, pktype); + if (key->type != pktype || (sshkey_type_plain(pktype) == KEY_ECDSA && + sshkey_ecdsa_nid_from_name(pkalg) != key->ecdsa_nid)) { + error_f("key type mismatch for decoded key " + "(received %s, expected %s)", sshkey_ssh_name(key), pkalg); goto done; } if (auth2_key_already_used(authctxt, key)) { @@ -319,20 +319,51 @@ match_principals_file(struct passwd *pw, char *file, struct sshkey_cert *cert, struct sshauthopt **authoptsp) { FILE *f; - int success; + int r, success = 0; + size_t i; + glob_t gl; + struct sshauthopt *opts = NULL; if (authoptsp != NULL) *authoptsp = NULL; temporarily_use_uid(pw); - debug("trying authorized principals file %s", file); - if ((f = auth_openprincipals(file, pw, options.strict_modes)) == NULL) { - restore_uid(); + r = glob(file, 0, NULL, &gl); + restore_uid(); + if (r != 0) { + if (r != GLOB_NOMATCH) { + logit_f("glob \"%s\" failed", file); + } return 0; + } else if (gl.gl_pathc > INT_MAX) { + fatal_f("too many glob results for \"%s\"", file); + } else if (gl.gl_pathc > 1) { + debug2_f("glob \"%s\" returned %zu matches", file, + gl.gl_pathc); + } + for (i = 0; !success && i < gl.gl_pathc; i++) { + temporarily_use_uid(pw); + debug("trying authorized principals file %s", file); + if ((f = auth_openprincipals(gl.gl_pathv[i], pw, + options.strict_modes)) == NULL) { + restore_uid(); + continue; + } + success = auth_process_principals(f, gl.gl_pathv[i], + cert, &opts); + fclose(f); + restore_uid(); + if (!success) { + sshauthopt_free(opts); + opts = NULL; + } } - success = auth_process_principals(f, file, cert, authoptsp); - fclose(f); - restore_uid(); + globfree(&gl); + if (success && authoptsp != NULL) { + *authoptsp = opts; + opts = NULL; + } + sshauthopt_free(opts); return success; } @@ -528,7 +559,7 @@ user_cert_trusted_ca(struct passwd *pw, struct sshkey *key, } if (use_authorized_principals && principals_opts == NULL) fatal_f("internal error: missing principals_opts"); - if (sshkey_cert_check_authority_now(key, 0, 1, 0, + if (sshkey_cert_check_authority_now(key, 0, 0, use_authorized_principals ? NULL : pw->pw_name, &reason) != 0) goto fail_reason; @@ -554,8 +585,14 @@ user_cert_trusted_ca(struct passwd *pw, struct sshkey *key, if ((final_opts = sshauthopt_merge(principals_opts, cert_opts, &reason)) == NULL) { fail_reason: - error("%s", reason); - auth_debug_add("%s", reason); + error("Refusing certificate ID \"%s\" serial=%llu " + "signed by %s CA %s: %s", key->cert->key_id, + (unsigned long long)key->cert->serial, + sshkey_type(key->cert->signature_key), ca_fp, + reason); + auth_debug_add("Refused Certificate ID \"%s\" " + "serial=%llu: %s", key->cert->key_id, + (unsigned long long)key->cert->serial, reason); goto out; } } @@ -753,8 +790,8 @@ int user_key_allowed(struct ssh *ssh, struct passwd *pw, struct sshkey *key, int auth_attempt, struct sshauthopt **authoptsp) { - u_int success = 0, i; - char *file, *conn_id; + u_int success = 0, i, j; + char *file = NULL, *conn_id; struct sshauthopt *opts = NULL; const char *rdomain, *remote_ip, *remote_host; @@ -776,17 +813,40 @@ user_key_allowed(struct ssh *ssh, struct passwd *pw, struct sshkey *key, remote_ip, ssh_remote_port(ssh)); for (i = 0; !success && i < options.num_authkeys_files; i++) { + int r; + glob_t gl; + if (strcasecmp(options.authorized_keys_files[i], "none") == 0) continue; file = expand_authorized_keys( options.authorized_keys_files[i], pw); - success = user_key_allowed2(pw, key, file, - remote_ip, remote_host, &opts); - free(file); - if (!success) { - sshauthopt_free(opts); - opts = NULL; + temporarily_use_uid(pw); + r = glob(file, 0, NULL, &gl); + restore_uid(); + if (r != 0) { + if (r != GLOB_NOMATCH) { + logit_f("glob \"%s\" failed", file); + } + free(file); + file = NULL; + continue; + } else if (gl.gl_pathc > INT_MAX) { + fatal_f("too many glob results for \"%s\"", file); + } else if (gl.gl_pathc > 1) { + debug2_f("glob \"%s\" returned %zu matches", file, + gl.gl_pathc); } + for (j = 0; !success && j < gl.gl_pathc; j++) { + success = user_key_allowed2(pw, key, gl.gl_pathv[j], + remote_ip, remote_host, &opts); + if (!success) { + sshauthopt_free(opts); + opts = NULL; + } + } + free(file); + file = NULL; + globfree(&gl); } if (success) goto out; diff --git a/auth2-pubkeyfile.c b/auth2-pubkeyfile.c index 31e7481..e729cc5 100644 --- a/auth2-pubkeyfile.c +++ b/auth2-pubkeyfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-pubkeyfile.c,v 1.4 2023/03/05 05:34:09 dtucker Exp $ */ +/* $OpenBSD: auth2-pubkeyfile.c,v 1.8 2026/04/02 07:48:13 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -50,6 +50,7 @@ #include "authfile.h" #include "match.h" #include "ssherr.h" +#include "xmalloc.h" int auth_authorise_keyopts(struct passwd *pw, struct sshauthopt *opts, @@ -146,20 +147,23 @@ auth_authorise_keyopts(struct passwd *pw, struct sshauthopt *opts, static int match_principals_option(const char *principal_list, struct sshkey_cert *cert) { - char *result; + char *list, *olist, *entry; u_int i; - /* XXX percent_expand() sequences for authorized_principals? */ - - for (i = 0; i < cert->nprincipals; i++) { - if ((result = match_list(cert->principals[i], - principal_list, NULL)) != NULL) { - debug3("matched principal from key options \"%.100s\"", - result); - free(result); - return 1; + olist = list = xstrdup(principal_list); + for (;;) { + if ((entry = strsep(&list, ",")) == NULL || *entry == '\0') + break; + for (i = 0; i < cert->nprincipals; i++) { + if (strcmp(entry, cert->principals[i]) == 0) { + debug3("matched principal from key i" + "options \"%.100s\"", entry); + free(olist); + return 1; + } } } + free(olist); return 0; } @@ -344,15 +348,15 @@ auth_check_authkey_line(struct passwd *pw, struct sshkey *key, /* Parse and check options present in certificate */ if ((certopts = sshauthopt_from_cert(key)) == NULL) { reason = "Invalid certificate options"; - goto fail_reason; + goto cert_fail_reason; } if (auth_authorise_keyopts(pw, certopts, 0, remote_ip, remote_host, loc) != 0) { reason = "Refused by certificate options"; - goto fail_reason; + goto cert_fail_reason; } if ((finalopts = sshauthopt_merge(keyopts, certopts, &reason)) == NULL) - goto fail_reason; + goto cert_fail_reason; /* * If the user has specified a list of principals as @@ -362,12 +366,12 @@ auth_check_authkey_line(struct passwd *pw, struct sshkey *key, if (keyopts->cert_principals != NULL && !match_principals_option(keyopts->cert_principals, key->cert)) { reason = "Certificate does not contain an authorized principal"; - goto fail_reason; + goto cert_fail_reason; } - if (sshkey_cert_check_authority_now(key, 0, 0, 0, + if (sshkey_cert_check_authority_now(key, 0, 0, keyopts->cert_principals == NULL ? pw->pw_name : NULL, &reason) != 0) - goto fail_reason; + goto cert_fail_reason; verbose("Accepted certificate ID \"%s\" (serial %llu) " "signed by CA %s %s found at %s", @@ -386,8 +390,17 @@ auth_check_authkey_line(struct passwd *pw, struct sshkey *key, ret = 0; goto out; + cert_fail_reason: + error("Refusing certificate ID \"%s\" serial=%llu " + "signed by %s CA %s via %s: %s", key->cert->key_id, + (unsigned long long)key->cert->serial, + sshkey_type(key->cert->signature_key), fp, loc, reason); + auth_debug_add("Refused Certificate ID \"%s\" serial=%llu: %s", + key->cert->key_id, (unsigned long long)key->cert->serial, reason); + goto out; + fail_reason: - error("%s", reason); + error("%s at %s", reason, loc); auth_debug_add("%s", reason); out: free(fp); diff --git a/auth2.c b/auth2.c index 67dec88..3a16827 100644 --- a/auth2.c +++ b/auth2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2.c,v 1.169 2024/05/17 00:30:23 djm Exp $ */ +/* $OpenBSD: auth2.c,v 1.173 2026/03/03 09:57:25 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -88,8 +88,8 @@ Authmethod *authmethods[] = { /* protocol */ -static int input_service_request(int, u_int32_t, struct ssh *); -static int input_userauth_request(int, u_int32_t, struct ssh *); +static int input_service_request(int, uint32_t, struct ssh *); +static int input_userauth_request(int, uint32_t, struct ssh *); /* helper */ static Authmethod *authmethod_byname(const char *); @@ -145,7 +145,7 @@ userauth_send_banner(struct ssh *ssh, const char *msg) (r = sshpkt_put_cstring(ssh, "")) != 0 || /* language, unused */ (r = sshpkt_send(ssh)) != 0) fatal_fr(r, "send packet"); - debug("%s: sent", __func__); + debug_f("sent"); } static void @@ -181,7 +181,7 @@ do_authentication2(struct ssh *ssh) } static int -input_service_request(int type, u_int32_t seq, struct ssh *ssh) +input_service_request(int type, uint32_t seq, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; char *service = NULL; @@ -238,7 +238,7 @@ user_specific_delay(const char *user) /* 0-4.2 ms of delay */ delay = (double)PEEK_U32(hash) / 1000 / 1000 / 1000 / 1000; freezero(hash, len); - debug3_f("user specific delay %0.3lfms", delay/1000); + debug3_f("user specific delay %0.3lfms", delay*1000); return MIN_FAIL_DELAY_SECONDS + delay; } @@ -266,7 +266,7 @@ ensure_minimum_time_since(double start, double seconds) } static int -input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) +input_userauth_request(int type, uint32_t seq, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; Authmethod *m = NULL; @@ -293,6 +293,8 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) /* setup auth context */ authctxt->pw = mm_getpwnamallow(ssh, user); authctxt->user = xstrdup(user); + authctxt->service = xstrdup(service); + authctxt->style = style ? xstrdup(style) : NULL; if (authctxt->pw && strcmp(service, "ssh-connection")==0) { authctxt->valid = 1; debug2_f("setting up authctxt for %s", user); @@ -311,8 +313,6 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) ssh_packet_set_log_preamble(ssh, "%suser %s", authctxt->valid ? "authenticating " : "invalid ", user); setproctitle("%s [net]", authctxt->valid ? user : "unknown"); - authctxt->service = xstrdup(service); - authctxt->style = style ? xstrdup(style) : NULL; mm_inform_authserv(service, style); userauth_banner(ssh); if ((r = kex_server_update_ext_info(ssh)) != 0) diff --git a/authfd.c b/authfd.c index e04ad0c..fe32261 100644 --- a/authfd.c +++ b/authfd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: authfd.c,v 1.134 2023/12/18 14:46:56 djm Exp $ */ +/* $OpenBSD: authfd.c,v 1.141 2026/03/05 05:44:15 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -43,22 +43,20 @@ #include #include -#include #include #include #include #include -#include "xmalloc.h" #include "ssh.h" #include "sshbuf.h" #include "sshkey.h" #include "authfd.h" -#include "cipher.h" #include "log.h" -#include "atomicio.h" #include "misc.h" +#include "atomicio.h" #include "ssherr.h" +#include "xmalloc.h" #define MAX_AGENT_IDENTITIES 2048 /* Max keys in agent reply */ #define MAX_AGENT_REPLY_LEN (256 * 1024) /* Max bytes in agent reply */ @@ -66,6 +64,7 @@ /* macro to check for "agent failure" message */ #define agent_failed(x) \ ((x == SSH_AGENT_FAILURE) || \ + (x == SSH_AGENT_EXTENSION_FAILURE) || \ (x == SSH_COM_AGENT2_FAILURE) || \ (x == SSH2_AGENT_FAILURE)) @@ -262,7 +261,7 @@ int ssh_fetch_identitylist(int sock, struct ssh_identitylist **idlp) { u_char type; - u_int32_t num, i; + uint32_t num, i; struct sshbuf *msg; struct ssh_identitylist *idl = NULL; int r; @@ -437,8 +436,15 @@ ssh_agent_sign(int sock, const struct sshkey *key, } if ((r = sshbuf_get_string(msg, &sig, &len)) != 0) goto out; - /* Check what we actually got back from the agent. */ - if ((r = sshkey_check_sigtype(sig, len, alg)) != 0) + /* + * Check what we actually got back from the agent, in case it returned + * an incorrect RSA signature algorithm (e.g. "ssh-rsa" (RSA/SHA1) vs. + * "rsa-sha2-256"). + * We don't do this for FIDO signatures as webauthn vs plain are just + * different signature formats and not entirely different algorithms. + */ + if (!sshkey_is_sk(key) && + (r = sshkey_check_sigtype(sig, len, alg)) != 0) goto out; /* success */ *sigp = sig; @@ -505,7 +511,7 @@ encode_dest_constraint(struct sshbuf *m, const struct dest_constraint *dc) static int encode_constraints(struct sshbuf *m, u_int life, u_int confirm, - u_int maxsign, const char *provider, + const char *provider, struct dest_constraint **dest_constraints, size_t ndest_constraints, int cert_only, struct sshkey **certs, size_t ncerts) { @@ -522,11 +528,6 @@ encode_constraints(struct sshbuf *m, u_int life, u_int confirm, if ((r = sshbuf_put_u8(m, SSH_AGENT_CONSTRAIN_CONFIRM)) != 0) goto out; } - if (maxsign != 0) { - if ((r = sshbuf_put_u8(m, SSH_AGENT_CONSTRAIN_MAXSIGN)) != 0 || - (r = sshbuf_put_u32(m, maxsign)) != 0) - goto out; - } if (provider != NULL) { if ((r = sshbuf_put_u8(m, SSH_AGENT_CONSTRAIN_EXTENSION)) != 0 || @@ -585,13 +586,12 @@ encode_constraints(struct sshbuf *m, u_int life, u_int confirm, */ int ssh_add_identity_constrained(int sock, struct sshkey *key, - const char *comment, u_int life, u_int confirm, u_int maxsign, + const char *comment, u_int life, u_int confirm, const char *provider, struct dest_constraint **dest_constraints, size_t ndest_constraints) { struct sshbuf *msg; - int r, constrained = (life || confirm || maxsign || - provider || dest_constraints); + int r, constrained = (life || confirm || provider || dest_constraints); u_char type; if ((msg = sshbuf_new()) == NULL) @@ -601,8 +601,6 @@ ssh_add_identity_constrained(int sock, struct sshkey *key, #ifdef WITH_OPENSSL case KEY_RSA: case KEY_RSA_CERT: - case KEY_DSA: - case KEY_DSA_CERT: case KEY_ECDSA: case KEY_ECDSA_CERT: case KEY_ECDSA_SK: @@ -612,14 +610,11 @@ ssh_add_identity_constrained(int sock, struct sshkey *key, case KEY_ED25519_CERT: case KEY_ED25519_SK: case KEY_ED25519_SK_CERT: - case KEY_XMSS: - case KEY_XMSS_CERT: type = constrained ? SSH2_AGENTC_ADD_ID_CONSTRAINED : SSH2_AGENTC_ADD_IDENTITY; if ((r = sshbuf_put_u8(msg, type)) != 0 || - (r = sshkey_private_serialize_maxsign(key, msg, maxsign, - 0)) != 0 || + (r = sshkey_private_serialize(key, msg)) != 0 || (r = sshbuf_put_cstring(msg, comment)) != 0) goto out; break; @@ -628,8 +623,8 @@ ssh_add_identity_constrained(int sock, struct sshkey *key, goto out; } if (constrained && - (r = encode_constraints(msg, life, confirm, maxsign, - provider, dest_constraints, ndest_constraints, 0, NULL, 0)) != 0) + (r = encode_constraints(msg, life, confirm, provider, + dest_constraints, ndest_constraints, 0, NULL, 0)) != 0) goto out; if ((r = ssh_request_reply_decode(sock, msg)) != 0) goto out; @@ -705,7 +700,7 @@ ssh_update_card(int sock, int add, const char *reader_id, const char *pin, (r = sshbuf_put_cstring(msg, pin)) != 0) goto out; if (constrained && - (r = encode_constraints(msg, life, confirm, 0, NULL, + (r = encode_constraints(msg, life, confirm, NULL, dest_constraints, ndest_constraints, cert_only, certs, ncerts)) != 0) goto out; @@ -776,3 +771,54 @@ ssh_agent_bind_hostkey(int sock, const struct sshkey *key, sshbuf_free(msg); return r; } + +/* Queries supported extension request types */ +int +ssh_agent_query_extensions(int sock, char ***exts) +{ + struct sshbuf *msg; + int r; + u_char type; + char *cp = NULL, **ret = NULL; + size_t i = 0; + + *exts = NULL; + if ((msg = sshbuf_new()) == NULL) + return SSH_ERR_ALLOC_FAIL; + if ((r = sshbuf_put_u8(msg, SSH_AGENTC_EXTENSION)) != 0 || + (r = sshbuf_put_cstring(msg, "query")) != 0) + goto out; + if ((r = ssh_request_reply(sock, msg, msg)) != 0) + goto out; + if ((r = sshbuf_get_u8(msg, &type)) != 0) + goto out; + if (agent_failed(type)) { + r = SSH_ERR_AGENT_FAILURE; + goto out; + } + /* Reply should start with "query" */ + if (type != SSH_AGENT_EXTENSION_RESPONSE || + (r = sshbuf_get_cstring(msg, &cp, NULL)) != 0 || + strcmp(cp, "query") != 0) { + r = SSH_ERR_INVALID_FORMAT; + goto out; + } + ret = calloc(1, sizeof(*ret)); + while (sshbuf_len(msg)) { + ret = xrecallocarray(ret, i + 1, i + 2, sizeof(*ret)); + if ((r = sshbuf_get_cstring(msg, ret + i, NULL)) != 0) { + r = SSH_ERR_INVALID_FORMAT; + goto out; + } + i++; + } + /* success */ + r = 0; + *exts = ret; + ret = NULL; /* transferred */ + out: + free(cp); + stringlist_free(ret); + sshbuf_free(msg); + return r; +} diff --git a/authfd.h b/authfd.h index c1e4b40..b2e07bc 100644 --- a/authfd.h +++ b/authfd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: authfd.h,v 1.52 2023/12/18 14:46:56 djm Exp $ */ +/* $OpenBSD: authfd.h,v 1.55 2026/03/05 05:44:15 djm Exp $ */ /* * Author: Tatu Ylonen @@ -48,9 +48,8 @@ int ssh_lock_agent(int sock, int lock, const char *password); int ssh_fetch_identitylist(int sock, struct ssh_identitylist **idlp); void ssh_free_identitylist(struct ssh_identitylist *idl); int ssh_add_identity_constrained(int sock, struct sshkey *key, - const char *comment, u_int life, u_int confirm, u_int maxsign, - const char *provider, struct dest_constraint **dest_constraints, - size_t ndest_constraints); + const char *comment, u_int life, u_int confirm, const char *provider, + struct dest_constraint **dest_constraints, size_t ndest_constraints); int ssh_agent_has_key(int sock, const struct sshkey *key); int ssh_remove_identity(int sock, const struct sshkey *key); int ssh_update_card(int sock, int add, const char *reader_id, @@ -68,6 +67,8 @@ int ssh_agent_bind_hostkey(int sock, const struct sshkey *key, const struct sshbuf *session_id, const struct sshbuf *signature, int forwarding); +int ssh_agent_query_extensions(int sock, char ***exts); + /* Messages for the authentication agent connection. */ #define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1 #define SSH_AGENT_RSA_IDENTITIES_ANSWER 2 @@ -103,10 +104,11 @@ int ssh_agent_bind_hostkey(int sock, const struct sshkey *key, /* generic extension mechanism */ #define SSH_AGENTC_EXTENSION 27 +#define SSH_AGENT_EXTENSION_FAILURE 28 +#define SSH_AGENT_EXTENSION_RESPONSE 29 #define SSH_AGENT_CONSTRAIN_LIFETIME 1 #define SSH_AGENT_CONSTRAIN_CONFIRM 2 -#define SSH_AGENT_CONSTRAIN_MAXSIGN 3 #define SSH_AGENT_CONSTRAIN_EXTENSION 255 /* extended failure messages */ diff --git a/authfile.c b/authfile.c index 445f2dd..5fc2ec4 100644 --- a/authfile.c +++ b/authfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: authfile.c,v 1.144 2023/03/14 07:26:25 dtucker Exp $ */ +/* $OpenBSD: authfile.c,v 1.149 2026/02/14 00:18:34 jsg Exp $ */ /* * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved. * @@ -27,7 +27,6 @@ #include #include -#include #include #include @@ -36,21 +35,14 @@ #include #include #include -#include -#include "cipher.h" -#include "ssh.h" #include "log.h" #include "authfile.h" -#include "misc.h" -#include "atomicio.h" #include "sshkey.h" #include "sshbuf.h" #include "ssherr.h" #include "krl.h" -#define MAX_KEY_FILE_SIZE (1024 * 1024) - /* Save a key blob to a file */ static int sshkey_save_private_blob(struct sshbuf *keybuf, const char *filename) @@ -133,8 +125,6 @@ sshkey_load_private_type(int type, const char *filename, const char *passphrase, goto out; r = sshkey_load_private_type_fd(fd, type, passphrase, keyp, commentp); - if (r == 0 && keyp && *keyp) - r = sshkey_set_filename(*keyp, filename); out: close(fd); return r; @@ -186,8 +176,6 @@ sshkey_load_pubkey_from_private(const char *filename, struct sshkey **pubkeyp) (r = sshkey_parse_pubkey_from_private_fileblob_type(buffer, KEY_UNSPEC, &pubkey)) != 0) goto out; - if ((r = sshkey_set_filename(pubkey, filename)) != 0) - goto out; /* success */ if (pubkeyp != NULL) { *pubkeyp = pubkey; @@ -330,11 +318,9 @@ sshkey_load_private_cert(int type, const char *filename, const char *passphrase, switch (type) { #ifdef WITH_OPENSSL case KEY_RSA: - case KEY_DSA: case KEY_ECDSA: #endif /* WITH_OPENSSL */ case KEY_ED25519: - case KEY_XMSS: case KEY_UNSPEC: break; default: diff --git a/buildpkg.sh.in b/buildpkg.sh.in index 15555cd..9a3bd1d 100644 --- a/buildpkg.sh.in +++ b/buildpkg.sh.in @@ -34,7 +34,7 @@ SSHDGID=67 # Default privsep gid #USR_LOCAL_IS_SYMLINK=yes # System V init run levels SYSVINITSTART=S98 -SYSVINITSTOPT=K30 +SYSVINITSTOP=K30 # We will source these if they exist POST_MAKE_INSTALL_FIXES=./pkg-post-make-install-fixes.sh POST_PROTOTYPE_EDITS=./pkg-post-prototype-edit.sh @@ -270,13 +270,13 @@ else cat > space << _EOF # extra space required by start/stop links added by installf # in postinstall -$TEST_DIR/etc/rc0.d/${SYSVINITSTOPT}${SYSVINIT_NAME} 0 1 +$TEST_DIR/etc/rc0.d/${SYSVINITSTOP}${SYSVINIT_NAME} 0 1 $TEST_DIR/etc/rc2.d/${SYSVINITSTART}${SYSVINIT_NAME} 0 1 _EOF [ "$RC1_D" = no ] || \ - echo "$TEST_DIR/etc/rc1.d/${SYSVINITSTOPT}${SYSVINIT_NAME} 0 1" >> space + echo "$TEST_DIR/etc/rc1.d/${SYSVINITSTOP}${SYSVINIT_NAME} 0 1" >> space [ "$RCS_D" = yes ] && \ - echo "$TEST_DIR/etc/rcS.d/${SYSVINITSTOPT}${SYSVINIT_NAME} 0 1" >> space + echo "$TEST_DIR/etc/rcS.d/${SYSVINITSTOP}${SYSVINIT_NAME} 0 1" >> space fi ## Build preinstall file @@ -338,17 +338,17 @@ else if [ "\${USE_SYM_LINKS}" = yes ] then [ "$RCS_D" = yes ] && \\ - installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rcS.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s - installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc0.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rcS.d/${SYSVINITSTOP}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc0.d/${SYSVINITSTOP}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s [ "$RC1_D" = no ] || \\ - installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc1.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc1.d/${SYSVINITSTOP}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc2.d/${SYSVINITSTART}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s else [ "$RCS_D" = yes ] && \\ - installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rcS.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l - installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc0.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rcS.d/${SYSVINITSTOP}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc0.d/${SYSVINITSTOP}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l [ "$RC1_D" = no ] || \\ - installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc1.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc1.d/${SYSVINITSTOP}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc2.d/${SYSVINITSTART}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l fi fi diff --git a/canohost.c b/canohost.c index 28f086e..4072562 100644 --- a/canohost.c +++ b/canohost.c @@ -1,4 +1,4 @@ -/* $OpenBSD: canohost.c,v 1.77 2023/03/31 04:42:29 dtucker Exp $ */ +/* $OpenBSD: canohost.c,v 1.78 2026/02/14 00:18:34 jsg Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -30,7 +30,6 @@ #include #include "xmalloc.h" -#include "packet.h" #include "log.h" #include "canohost.h" #include "misc.h" @@ -41,7 +40,7 @@ ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len) struct sockaddr_in6 *a6 = (struct sockaddr_in6 *)addr; struct sockaddr_in *a4 = (struct sockaddr_in *)addr; struct in_addr inaddr; - u_int16_t port; + uint16_t port; if (addr->ss_family != AF_INET6 || !IN6_IS_ADDR_V4MAPPED(&a6->sin6_addr)) diff --git a/chacha.c b/chacha.c index 729aa03..9d79b66 100644 --- a/chacha.c +++ b/chacha.c @@ -48,8 +48,8 @@ typedef struct chacha_ctx chacha_ctx; a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \ c = PLUS(c,d); b = ROTATE(XOR(b,c), 7); -static const char sigma[16] = "expand 32-byte k"; -static const char tau[16] = "expand 16-byte k"; +static const char __attribute__ ((__nonstring__)) sigma[16] = "expand 32-byte k"; +static const char __attribute__ ((__nonstring__)) tau[16] = "expand 16-byte k"; void chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits) diff --git a/channels.c b/channels.c index a23fde4..d7c55fc 100644 --- a/channels.c +++ b/channels.c @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.c,v 1.439 2024/07/25 22:40:08 djm Exp $ */ +/* $OpenBSD: channels.c,v 1.458 2026/03/28 05:16:18 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -46,9 +46,7 @@ #include #include #include -#ifdef HAVE_SYS_TIME_H -# include -#endif +#include #include #include @@ -57,20 +55,15 @@ #include #include #include -#ifdef HAVE_POLL_H #include -#endif #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include #include #include #include -#include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "ssh.h" #include "ssh2.h" @@ -82,8 +75,6 @@ #include "channels.h" #include "compat.h" #include "canohost.h" -#include "sshkey.h" -#include "authfd.h" #include "pathnames.h" #include "match.h" @@ -94,6 +85,8 @@ #define NUM_SOCKS 10 /* -- X11 forwarding */ +/* X11 port for display :0 */ +#define X11_BASE_PORT 6000 /* Maximum number of fake X11 displays to try. */ #define MAX_DISPLAYS 1000 @@ -210,6 +203,10 @@ struct ssh_channels { /* Global timeout for all OPEN channels */ int global_deadline; time_t lastused; + /* pattern-lists used to classify channels as bulk */ + char *bulk_classifier_tty, *bulk_classifier_notty; + /* Number of active bulk channels (set by channel_handler) */ + u_int nbulk; }; /* helper */ @@ -237,6 +234,8 @@ channel_init_channels(struct ssh *ssh) sc->channels_alloc = 10; sc->channels = xcalloc(sc->channels_alloc, sizeof(*sc->channels)); sc->IPv4or6 = AF_UNSPEC; + sc->bulk_classifier_tty = xstrdup(CHANNEL_BULK_TTY); + sc->bulk_classifier_notty = xstrdup(CHANNEL_BULK_NOTTY); channel_handler_init(sc); ssh->chanctxt = sc; @@ -355,6 +354,17 @@ lookup_timeout(struct ssh *ssh, const char *type) return 0; } +static void +channel_classify(struct ssh *ssh, Channel *c) +{ + struct ssh_channels *sc = ssh->chanctxt; + const char *type = c->xctype == NULL ? c->ctype : c->xctype; + const char *classifier = (c->isatty || c->remote_has_tty) ? + sc->bulk_classifier_tty : sc->bulk_classifier_notty; + + c->bulk = type != NULL && match_pattern_list(type, classifier, 0) == 1; +} + /* * Sets "extended type" of a channel; used by session layer to add additional * information about channel types (e.g. shell, login, subsystem) that can then @@ -373,6 +383,7 @@ channel_set_xtype(struct ssh *ssh, int id, const char *xctype) c->xctype = xstrdup(xctype); /* Type has changed, so look up inactivity deadline again */ c->inactive_deadline = lookup_timeout(ssh, c->xctype); + channel_classify(ssh, c); debug2_f("labeled channel %d as %s (inactive timeout %u)", id, xctype, c->inactive_deadline); } @@ -409,6 +420,13 @@ channel_get_expiry(struct ssh *ssh, Channel *c) return expiry; } +/* Returns non-zero if there is an open, non-interactive channel */ +int +channel_has_bulk(struct ssh *ssh) +{ + return ssh->chanctxt != NULL && ssh->chanctxt->nbulk != 0; +} + /* * Register filedescriptors for a channel, used when allocating a channel or * when the channel consumer/producer is ready, e.g. shell exec'd @@ -476,6 +494,7 @@ channel_register_fds(struct ssh *ssh, Channel *c, int rfd, int wfd, int efd, } /* channel might be entering a larval state, so reset global timeout */ channel_set_used_time(ssh, NULL); + channel_classify(ssh, c); } /* @@ -535,11 +554,19 @@ channel_new(struct ssh *ssh, char *ctype, int type, int rfd, int wfd, int efd, c->delayed = 1; /* prevent call to channel_post handler */ c->inactive_deadline = lookup_timeout(ssh, c->ctype); TAILQ_INIT(&c->status_confirms); + channel_classify(ssh, c); debug("channel %d: new %s [%s] (inactive timeout: %u)", found, c->ctype, remote_name, c->inactive_deadline); return c; } +void +channel_set_tty(struct ssh *ssh, Channel *c) +{ + c->remote_has_tty = 1; + channel_classify(ssh, c); +} + int channel_close_fd(struct ssh *ssh, Channel *c, int *fdp) { @@ -825,6 +852,27 @@ channel_free_all(struct ssh *ssh) sc->x11_fake_data_len = 0; } +void +channel_free_channels(struct ssh *ssh) +{ + struct ssh_channels *sc; + + if (ssh == NULL || ssh->chanctxt == NULL) + return; + channel_free_all(ssh); + channel_clear_permission(ssh, FORWARD_USER, FORWARD_LOCAL); + channel_clear_permission(ssh, FORWARD_USER, FORWARD_REMOTE); + channel_clear_permission(ssh, FORWARD_ADM, FORWARD_LOCAL); + channel_clear_permission(ssh, FORWARD_ADM, FORWARD_REMOTE); + sc = ssh->chanctxt; + free(sc->bulk_classifier_tty); + free(sc->bulk_classifier_notty); + free(sc->channel_pre); + free(sc->channel_post); + freezero(sc, sizeof(*sc)); + ssh->chanctxt = NULL; +} + /* * Closes the sockets/fds of all channels. This is used to close extra file * descriptors after a fork. @@ -1017,7 +1065,7 @@ channel_format_status(const Channel *c) char *ret = NULL; xasprintf(&ret, "t%d [%s] %s%u %s%u i%u/%zu o%u/%zu e[%s]/%zu " - "fd %d/%d/%d sock %d cc %d %s%u io 0x%02x/0x%02x", + "fd %d/%d/%d sock %d cc %d %s%u io 0x%02x/0x%02x %s%s", c->type, c->xctype != NULL ? c->xctype : c->ctype, c->have_remote_id ? "r" : "nr", c->remote_id, c->mux_ctx != NULL ? "m" : "nm", c->mux_downstream_id, @@ -1026,7 +1074,9 @@ channel_format_status(const Channel *c) channel_format_extended_usage(c), sshbuf_len(c->extended), c->rfd, c->wfd, c->efd, c->sock, c->ctl_chan, c->have_ctl_child_id ? "c" : "nc", c->ctl_child_id, - c->io_want, c->io_ready); + c->io_want, c->io_ready, + c->isatty ? "T" : (c->remote_has_tty ? "RT" : ""), + c->bulk ? "B" : "I"); return ret; } @@ -1094,6 +1144,21 @@ channel_open_message(struct ssh *ssh) return ret; } +void +channel_report_open(struct ssh *ssh, int level) +{ + char *open, *oopen, *cp, ident[256]; + + sshpkt_fmt_connection_id(ssh, ident, sizeof(ident)); + do_log2(level, "Connection: %s (pid %ld)", ident, (long)getpid()); + open = oopen = channel_open_message(ssh); + while ((cp = strsep(&open, "\r\n")) != NULL) { + if (*cp != '\0') + do_log2(level, "%s", cp); + } + free(oopen); +} + static void open_preamble(struct ssh *ssh, const char *where, Channel *c, const char *type) { @@ -1125,7 +1190,8 @@ channel_send_open(struct ssh *ssh, int id) } void -channel_request_start(struct ssh *ssh, int id, char *service, int wantconfirm) +channel_request_start(struct ssh *ssh, int id, const char *service, + int wantconfirm) { Channel *c = channel_lookup(ssh, id); int r; @@ -1439,115 +1505,93 @@ channel_pre_mux_client(struct ssh *ssh, Channel *c) } } +static inline int +socks_decode_error(Channel *c, int status, const char *func, const char *msg) +{ + if (status == SSH_ERR_MESSAGE_INCOMPLETE) + return 0; + else { + debug_r(status, "%s: channel %d: decode %s", + func, c->self, msg); + return -1; + } +} + /* try to decode a socks4 header */ static int channel_decode_socks4(Channel *c, struct sshbuf *input, struct sshbuf *output) { - const u_char *p; - char *host; - u_int len, have, i, found, need; - char username[256]; - struct { - u_int8_t version; - u_int8_t command; - u_int16_t dest_port; - struct in_addr dest_addr; - } s4_req, s4_rsp; - int r; - - debug2("channel %d: decode socks4", c->self); + uint8_t socks_ver, socks_cmd, dest_addr[4]; + uint16_t dest_port; + char *user = NULL, *host = NULL; + int success = -1, socks4a = 0, r; + struct sshbuf *b = NULL; - have = sshbuf_len(input); - len = sizeof(s4_req); - if (have < len) - return 0; - p = sshbuf_ptr(input); - - need = 1; - /* SOCKS4A uses an invalid IP address 0.0.0.x */ - if (p[4] == 0 && p[5] == 0 && p[6] == 0 && p[7] != 0) { - debug2("channel %d: socks4a request", c->self); - /* ... and needs an extra string (the hostname) */ - need = 2; - } - /* Check for terminating NUL on the string(s) */ - for (found = 0, i = len; i < have; i++) { - if (p[i] == '\0') { - found++; - if (found == need) - break; - } - if (i > 1024) { - /* the peer is probably sending garbage */ - debug("channel %d: decode socks4: too long", - c->self); - return -1; - } - } - if (found < need) + if (sshbuf_len(input) < 9) return 0; - if ((r = sshbuf_get(input, &s4_req.version, 1)) != 0 || - (r = sshbuf_get(input, &s4_req.command, 1)) != 0 || - (r = sshbuf_get(input, &s4_req.dest_port, 2)) != 0 || - (r = sshbuf_get(input, &s4_req.dest_addr, 4)) != 0) { - debug_r(r, "channels %d: decode socks4", c->self); - return -1; - } - have = sshbuf_len(input); - p = sshbuf_ptr(input); - if (memchr(p, '\0', have) == NULL) { - error("channel %d: decode socks4: unterminated user", c->self); - return -1; + + /* We may not have a complete message, so work on a dup of the buffer */ + if ((b = sshbuf_fromb(input)) == NULL) + fatal_f("sshbuf_fromb failed"); + + debug2("channel %d: decode socks4", c->self); + if ((r = sshbuf_get_u8(b, &socks_ver)) != 0 || + (r = sshbuf_get_u8(b, &socks_cmd)) != 0 || + (r = sshbuf_get_u16(b, &dest_port)) != 0 || + (r = sshbuf_get(b, &dest_addr, sizeof(dest_addr))) != 0 || + (r = sshbuf_get_nulterminated_string(b, 1024, &user, NULL)) != 0) { + success = socks_decode_error(c, r, __func__, "header"); + goto out; } - len = strlen(p); - debug2("channel %d: decode socks4: user %s/%d", c->self, p, len); - len++; /* trailing '\0' */ - strlcpy(username, p, sizeof(username)); - if ((r = sshbuf_consume(input, len)) != 0) - fatal_fr(r, "channel %d: consume", c->self); - free(c->path); - c->path = NULL; - if (need == 1) { /* SOCKS4: one string */ - host = inet_ntoa(s4_req.dest_addr); - c->path = xstrdup(host); - } else { /* SOCKS4A: two strings */ - have = sshbuf_len(input); - p = sshbuf_ptr(input); - if (memchr(p, '\0', have) == NULL) { - error("channel %d: decode socks4a: host not nul " - "terminated", c->self); - return -1; - } - len = strlen(p); - debug2("channel %d: decode socks4a: host %s/%d", - c->self, p, len); - len++; /* trailing '\0' */ - if (len > NI_MAXHOST) { - error("channel %d: hostname \"%.100s\" too long", - c->self, p); - return -1; + + /* Is this a SOCKS4A request? (indicated by an address of 0.0.0.x) */ + if (dest_addr[0] == 0 && dest_addr[1] == 0 && + dest_addr[2] == 0 && dest_addr[3] != 0) { + /* If so, then the hostname follows, also nul-terminated */ + if ((r = sshbuf_get_nulterminated_string(b, 1024, + &host, NULL)) != 0) { + success = socks_decode_error(c, r, __func__, "host"); + goto out; } - c->path = xstrdup(p); - if ((r = sshbuf_consume(input, len)) != 0) - fatal_fr(r, "channel %d: consume", c->self); + socks4a = 1; + } else { + /* Plain SOCKS4 passes an IPv4 binary address; reconstruct */ + xasprintf(&host, "%d.%d.%d.%d", + dest_addr[0], dest_addr[1], dest_addr[2], dest_addr[3]); } - c->host_port = ntohs(s4_req.dest_port); - debug2("channel %d: dynamic request: socks4 host %s port %u command %u", - c->self, c->path, c->host_port, s4_req.command); + /* We have a complete SOCKS4 message; consume it from input */ + if ((r = sshbuf_consume_upto_child(input, b)) != 0) + fatal_fr(r, "channel %d: consume", c->self); - if (s4_req.command != 1) { - debug("channel %d: cannot handle: %s cn %d", - c->self, need == 1 ? "SOCKS4" : "SOCKS4A", s4_req.command); - return -1; + /* Handle the request */ + debug2("channel %d: %s: user=\"%s\" command=%d destination=[%s]:%d", + c->self, socks4a ? "SOCKS4A" : "SOCKS4", user, (int)socks_cmd, + host, dest_port); + if (socks_cmd != 1) { + debug("channel %d: cannot handle %s command 0x%02x", + c->self, socks4a ? "SOCKS4A" : "SOCKS4", socks_cmd); + goto out; } - s4_rsp.version = 0; /* vn: 0 for reply */ - s4_rsp.command = 90; /* cd: req granted */ - s4_rsp.dest_port = 0; /* ignored */ - s4_rsp.dest_addr.s_addr = INADDR_ANY; /* ignored */ - if ((r = sshbuf_put(output, &s4_rsp, sizeof(s4_rsp))) != 0) - fatal_fr(r, "channel %d: append reply", c->self); - return 1; + free(c->path); + c->path = host; + host = NULL; /* transferred */ + c->host_port = dest_port; + + /* Reply to the SOCKS4 client */ + if ((r = sshbuf_put_u8(output, 0)) != 0 || /* vn: 0 for reply */ + (r = sshbuf_put_u8(output, 90)) != 0 || /* cd: req granted */ + (r = sshbuf_put_u16(output, 0)) != 0 || /* port: ignored */ + (r = sshbuf_put_u32(output, ntohl(INADDR_ANY))) != 0) /* ignored */ + fatal_fr(r, "channel %d: compose reply", c->self); + + /* success */ + success = 1; + out: + sshbuf_free(b); + free(user); + free(host); + return success; } /* try to decode a socks5 header */ @@ -1559,73 +1603,110 @@ channel_decode_socks4(Channel *c, struct sshbuf *input, struct sshbuf *output) #define SSH_SOCKS5_CONNECT 0x01 #define SSH_SOCKS5_SUCCESS 0x00 +/* + * Handles SOCKS5 authentication. Note 'b' must be a dup of 'input' + * Returns 0 on insufficient queued date, 1 on authentication success or + * -1 on error. + */ +static int +channel_socks5_check_auth(Channel *c, struct sshbuf *b, struct sshbuf *input, + struct sshbuf *output) +{ + uint8_t socks_ver; + uint8_t nmethods, method; + int r; + u_int i, found; + + /* format: ver | nmethods | methods */ + if ((r = sshbuf_get_u8(b, &socks_ver)) != 0) + return socks_decode_error(c, r, __func__, "version"); + if (socks_ver != 5) /* shouldn't happen; checked by caller^2 */ + fatal_fr(r, "channel %d: internal error: not socks5", c->self); + if ((r = sshbuf_get_u8(b, &nmethods)) != 0) + return socks_decode_error(c, r, __func__, "methods"); + for (found = i = 0; i < nmethods; i++) { + if ((r = sshbuf_get_u8(b, &method)) != 0) + return socks_decode_error(c, r, __func__, "method"); + if (method == SSH_SOCKS5_NOAUTH) + found = 1; + } + if (!found) { + debug("channel %d: didn't request SSH_SOCKS5_NOAUTH", c->self); + return -1; + } + /* Consume completed request */ + if ((r = sshbuf_consume_upto_child(input, b)) != 0) + fatal_fr(r, "channel %d: consume", c->self); + + /* Compose reply: version, method */ + if ((r = sshbuf_put_u8(output, 0x05)) != 0 || + (r = sshbuf_put_u8(output, SSH_SOCKS5_NOAUTH)) != 0) + fatal_fr(r, "channel %d: append reply", c->self); + /* success */ + debug2("channel %d: socks5 auth done", c->self); + return 1; +} + static int channel_decode_socks5(Channel *c, struct sshbuf *input, struct sshbuf *output) { - /* XXX use get/put_u8 instead of trusting struct padding */ - struct { - u_int8_t version; - u_int8_t command; - u_int8_t reserved; - u_int8_t atyp; - } s5_req, s5_rsp; - u_int16_t dest_port; + uint8_t socks_ver, socks_cmd, socks_reserved, socks_atyp, addrlen; + uint16_t dest_port; char dest_addr[255+1], ntop[INET6_ADDRSTRLEN]; - const u_char *p; - u_int have, need, i, found, nmethods, addrlen, af; - int r; + u_int af; + int r, success = -1;; + struct sshbuf *b = NULL; + + debug2("channel %d: decode socks5 %s", c->self, + (c->flags & SSH_SOCKS5_AUTHDONE) ? "request" : "auth"); + + /* We may not have a complete message, so work on a dup of the buffer */ + if ((b = sshbuf_fromb(input)) == NULL) + fatal_f("sshbuf_fromb failed"); - debug2("channel %d: decode socks5", c->self); - p = sshbuf_ptr(input); - if (p[0] != 0x05) - return -1; - have = sshbuf_len(input); if (!(c->flags & SSH_SOCKS5_AUTHDONE)) { - /* format: ver | nmethods | methods */ - if (have < 2) - return 0; - nmethods = p[1]; - if (have < nmethods + 2) - return 0; - /* look for method: "NO AUTHENTICATION REQUIRED" */ - for (found = 0, i = 2; i < nmethods + 2; i++) { - if (p[i] == SSH_SOCKS5_NOAUTH) { - found = 1; - break; - } - } - if (!found) { - debug("channel %d: method SSH_SOCKS5_NOAUTH not found", - c->self); - return -1; + if ((r = channel_socks5_check_auth(c, b, input, output)) != 1) { + success = r; + goto out; } - if ((r = sshbuf_consume(input, nmethods + 2)) != 0) - fatal_fr(r, "channel %d: consume", c->self); - /* version, method */ - if ((r = sshbuf_put_u8(output, 0x05)) != 0 || - (r = sshbuf_put_u8(output, SSH_SOCKS5_NOAUTH)) != 0) - fatal_fr(r, "channel %d: append reply", c->self); c->flags |= SSH_SOCKS5_AUTHDONE; - debug2("channel %d: socks5 auth done", c->self); - return 0; /* need more */ + /* Continue to parse request in case client speculated ahead */ } + + /* Request messages (auth or connect) always start with the version */ + if ((r = sshbuf_get_u8(b, &socks_ver)) != 0) { + success = socks_decode_error(c, r, __func__, "version"); + goto out; + } + if (socks_ver != 5) /* shouldn't happen */ + fatal_fr(r, "channel %d: internal error: not socks5", c->self); + + /* Parse SOCKS5 request header */ debug2("channel %d: socks5 post auth", c->self); - if (have < sizeof(s5_req)+1) - return 0; /* need more */ - memcpy(&s5_req, p, sizeof(s5_req)); - if (s5_req.version != 0x05 || - s5_req.command != SSH_SOCKS5_CONNECT || - s5_req.reserved != 0x00) { + if ((r = sshbuf_get_u8(b, &socks_cmd)) != 0 || + (r = sshbuf_get_u8(b, &socks_reserved)) != 0 || + (r = sshbuf_get_u8(b, &socks_atyp)) != 0) { + success = socks_decode_error(c, r, __func__, "request header"); + goto out; + } + + if (socks_ver != 0x05 || + socks_cmd != SSH_SOCKS5_CONNECT || + socks_reserved != 0x00) { debug2("channel %d: only socks5 connect supported", c->self); - return -1; + goto out; } - switch (s5_req.atyp){ + + switch (socks_atyp) { case SSH_SOCKS5_IPV4: addrlen = 4; af = AF_INET; break; case SSH_SOCKS5_DOMAIN: - addrlen = p[sizeof(s5_req)]; + if ((r = sshbuf_get_u8(b, &addrlen)) != 0) { + success = socks_decode_error(c, r, __func__, "addrlen"); + goto out; + } af = -1; break; case SSH_SOCKS5_IPV6: @@ -1633,57 +1714,48 @@ channel_decode_socks5(Channel *c, struct sshbuf *input, struct sshbuf *output) af = AF_INET6; break; default: - debug2("channel %d: bad socks5 atyp %d", c->self, s5_req.atyp); - return -1; - } - need = sizeof(s5_req) + addrlen + 2; - if (s5_req.atyp == SSH_SOCKS5_DOMAIN) - need++; - if (have < need) - return 0; - if ((r = sshbuf_consume(input, sizeof(s5_req))) != 0) - fatal_fr(r, "channel %d: consume", c->self); - if (s5_req.atyp == SSH_SOCKS5_DOMAIN) { - /* host string length */ - if ((r = sshbuf_consume(input, 1)) != 0) - fatal_fr(r, "channel %d: consume", c->self); + debug2("channel %d: bad socks5 atyp %d", c->self, socks_atyp); + goto out; } - if ((r = sshbuf_get(input, &dest_addr, addrlen)) != 0 || - (r = sshbuf_get(input, &dest_port, 2)) != 0) { - debug_r(r, "channel %d: parse addr/port", c->self); - return -1; + if ((r = sshbuf_get(b, &dest_addr, addrlen)) != 0 || + (r = sshbuf_get_u16(b, &dest_port)) != 0) { + success = socks_decode_error(c, r, __func__, "addr/port"); + goto out; } dest_addr[addrlen] = '\0'; + + /* We have a complete SOCKS5 request; consume it from input */ + if ((r = sshbuf_consume_upto_child(input, b)) != 0) + fatal_fr(r, "channel %d: consume", c->self); + free(c->path); c->path = NULL; - if (s5_req.atyp == SSH_SOCKS5_DOMAIN) { - if (addrlen >= NI_MAXHOST) { - error("channel %d: dynamic request: socks5 hostname " - "\"%.100s\" too long", c->self, dest_addr); - return -1; - } + if (socks_atyp == SSH_SOCKS5_DOMAIN) c->path = xstrdup(dest_addr); - } else { + else { if (inet_ntop(af, dest_addr, ntop, sizeof(ntop)) == NULL) return -1; c->path = xstrdup(ntop); } - c->host_port = ntohs(dest_port); + c->host_port = dest_port; debug2("channel %d: dynamic request: socks5 host %s port %u command %u", - c->self, c->path, c->host_port, s5_req.command); - - s5_rsp.version = 0x05; - s5_rsp.command = SSH_SOCKS5_SUCCESS; - s5_rsp.reserved = 0; /* ignored */ - s5_rsp.atyp = SSH_SOCKS5_IPV4; - dest_port = 0; /* ignored */ - - if ((r = sshbuf_put(output, &s5_rsp, sizeof(s5_rsp))) != 0 || - (r = sshbuf_put_u32(output, ntohl(INADDR_ANY))) != 0 || - (r = sshbuf_put(output, &dest_port, sizeof(dest_port))) != 0) + c->self, c->path, c->host_port, socks_cmd); + + /* Reply */ + if ((r = sshbuf_put_u8(output, 0x05)) != 0 || /* version */ + (r = sshbuf_put_u8(output, SSH_SOCKS5_SUCCESS)) != 0 || /* cmd */ + (r = sshbuf_put_u8(output, 0)) != 0 || /* reserved, ignored */ + (r = sshbuf_put_u8(output, SSH_SOCKS5_IPV4)) != 0 || /* addrtype */ + (r = sshbuf_put_u32(output, ntohl(INADDR_ANY))) != 0 || /* addr */ + (r = sshbuf_put_u16(output, dest_port)) != 0) /* port */ fatal_fr(r, "channel %d: append reply", c->self); - return 1; + + /* success */ + success = 1; + out: + sshbuf_free(b); + return success; } Channel * @@ -1715,9 +1787,9 @@ channel_connect_stdio_fwd(struct ssh *ssh, static void channel_pre_dynamic(struct ssh *ssh, Channel *c) { - const u_char *p; u_int have; - int ret; + u_char ver; + int r, ret; c->io_want = 0; have = sshbuf_len(c->input); @@ -1730,9 +1802,9 @@ channel_pre_dynamic(struct ssh *ssh, Channel *c) return; } /* try to guess the protocol */ - p = sshbuf_ptr(c->input); - /* XXX sshbuf_peek_u8? */ - switch (p[0]) { + if ((r = sshbuf_peek_u8(c->input, 0, &ver)) != 0) + fatal_fr(r, "sshbuf_peek_u8"); + switch (ver) { case 0x04: ret = channel_decode_socks4(c, c->input, c->output); break; @@ -1740,6 +1812,7 @@ channel_pre_dynamic(struct ssh *ssh, Channel *c) ret = channel_decode_socks5(c, c->input, c->output); break; default: + debug2_f("channel %d: unknown SOCKS version %u", c->self, ver); ret = -1; break; } @@ -2024,7 +2097,8 @@ channel_post_auth_listener(struct ssh *ssh, Channel *c) SSH_CHANNEL_OPENING, newsock, newsock, -1, c->local_window_max, c->local_maxpacket, 0, "accepted auth socket", 1); - open_preamble(ssh, __func__, nc, "auth-agent@openssh.com"); + open_preamble(ssh, __func__, nc, + c->agent_new ? "agent-connect" : "auth-agent@openssh.com"); if ((r = sshpkt_send(ssh)) != 0) fatal_fr(r, "channel %i", c->self); } @@ -2604,10 +2678,13 @@ channel_handler(struct ssh *ssh, int table, struct timespec *timeout) time_t now; now = monotime(); - for (i = 0, oalloc = sc->channels_alloc; i < oalloc; i++) { + for (sc->nbulk = i = 0, oalloc = sc->channels_alloc; i < oalloc; i++) { c = sc->channels[i]; if (c == NULL) continue; + /* Count open channels in bulk state */ + if (c->type == SSH_CHANNEL_OPEN && c->bulk) + sc->nbulk++; /* Try to keep IO going while rekeying */ if (ssh_packet_is_rekeying(ssh) && c->type != SSH_CHANNEL_OPEN) continue; @@ -3286,7 +3363,7 @@ channel_proxy_downstream(struct ssh *ssh, Channel *downstream) * replaces local (proxy) channel ID with downstream channel ID. */ int -channel_proxy_upstream(Channel *c, int type, u_int32_t seq, struct ssh *ssh) +channel_proxy_upstream(Channel *c, int type, uint32_t seq, struct ssh *ssh) { struct sshbuf *b = NULL; Channel *downstream; @@ -3369,7 +3446,7 @@ channel_proxy_upstream(Channel *c, int type, u_int32_t seq, struct ssh *ssh) static int channel_parse_id(struct ssh *ssh, const char *where, const char *what) { - u_int32_t id; + uint32_t id; int r; if ((r = sshpkt_get_u32(ssh, &id)) != 0) { @@ -3398,7 +3475,7 @@ channel_from_packet_id(struct ssh *ssh, const char *where, const char *what) } int -channel_input_data(int type, u_int32_t seq, struct ssh *ssh) +channel_input_data(int type, uint32_t seq, struct ssh *ssh) { const u_char *data; size_t data_len, win_len; @@ -3430,7 +3507,10 @@ channel_input_data(int type, u_int32_t seq, struct ssh *ssh) * updates are sent back. Otherwise the connection might deadlock. */ if (c->ostate != CHAN_OUTPUT_OPEN) { - c->local_window -= win_len; + if (win_len > c->local_window) + c->local_window = 0; + else + c->local_window -= win_len; c->local_consumed += win_len; return 0; } @@ -3466,11 +3546,11 @@ channel_input_data(int type, u_int32_t seq, struct ssh *ssh) } int -channel_input_extended_data(int type, u_int32_t seq, struct ssh *ssh) +channel_input_extended_data(int type, uint32_t seq, struct ssh *ssh) { const u_char *data; size_t data_len; - u_int32_t tcode; + uint32_t tcode; Channel *c = channel_from_packet_id(ssh, __func__, "extended data"); int r; @@ -3519,7 +3599,7 @@ channel_input_extended_data(int type, u_int32_t seq, struct ssh *ssh) } int -channel_input_ieof(int type, u_int32_t seq, struct ssh *ssh) +channel_input_ieof(int type, uint32_t seq, struct ssh *ssh) { Channel *c = channel_from_packet_id(ssh, __func__, "ieof"); int r; @@ -3544,7 +3624,7 @@ channel_input_ieof(int type, u_int32_t seq, struct ssh *ssh) } int -channel_input_oclose(int type, u_int32_t seq, struct ssh *ssh) +channel_input_oclose(int type, uint32_t seq, struct ssh *ssh) { Channel *c = channel_from_packet_id(ssh, __func__, "oclose"); int r; @@ -3560,10 +3640,10 @@ channel_input_oclose(int type, u_int32_t seq, struct ssh *ssh) } int -channel_input_open_confirmation(int type, u_int32_t seq, struct ssh *ssh) +channel_input_open_confirmation(int type, uint32_t seq, struct ssh *ssh) { Channel *c = channel_from_packet_id(ssh, __func__, "open confirmation"); - u_int32_t remote_window, remote_maxpacket; + uint32_t remote_window, remote_maxpacket; int r; if (channel_proxy_upstream(c, type, seq, ssh)) @@ -3615,10 +3695,10 @@ reason2txt(int reason) } int -channel_input_open_failure(int type, u_int32_t seq, struct ssh *ssh) +channel_input_open_failure(int type, uint32_t seq, struct ssh *ssh) { Channel *c = channel_from_packet_id(ssh, __func__, "open failure"); - u_int32_t reason; + uint32_t reason; char *msg = NULL; int r; @@ -3652,11 +3732,11 @@ channel_input_open_failure(int type, u_int32_t seq, struct ssh *ssh) } int -channel_input_window_adjust(int type, u_int32_t seq, struct ssh *ssh) +channel_input_window_adjust(int type, uint32_t seq, struct ssh *ssh) { int id = channel_parse_id(ssh, __func__, "window adjust"); Channel *c; - u_int32_t adjust; + uint32_t adjust; u_int new_rwin; int r; @@ -3682,7 +3762,7 @@ channel_input_window_adjust(int type, u_int32_t seq, struct ssh *ssh) } int -channel_input_status_confirm(int type, u_int32_t seq, struct ssh *ssh) +channel_input_status_confirm(int type, uint32_t seq, struct ssh *ssh) { int id = channel_parse_id(ssh, __func__, "status confirm"); Channel *c; @@ -4516,7 +4596,7 @@ channel_add_permission(struct ssh *ssh, int who, int where, * host/port_to_connect. */ permission_set_add(ssh, who, where, - local ? host : 0, local ? port : 0, + local ? host : NULL, local ? port : 0, local ? NULL : host, NULL, local ? 0 : port, NULL); pset->all_permitted = 0; } @@ -4539,10 +4619,13 @@ void channel_clear_permission(struct ssh *ssh, int who, int where) { struct permission **permp; - u_int *npermp; + u_int i, *npermp; permission_set_get_array(ssh, who, where, &permp, &npermp); - *permp = xrecallocarray(*permp, *npermp, 0, sizeof(**permp)); + for (i = 0; i < *npermp; i++) + fwd_perm_clear((*permp) + i); + free(*permp); + *permp = NULL; *npermp = 0; } @@ -4673,10 +4756,9 @@ connect_to_helper(struct ssh *ssh, const char *name, int port, int socktype, /* * Fake up a struct addrinfo for AF_UNIX connections. * channel_connect_ctx_free() must check ai_family - * and use free() not freeaddirinfo() for AF_UNIX. + * and use free() not freeaddrinfo() for AF_UNIX. */ - ai = xmalloc(sizeof(*ai) + sizeof(*sunaddr)); - memset(ai, 0, sizeof(*ai) + sizeof(*sunaddr)); + ai = xcalloc(1, sizeof(*ai) + sizeof(*sunaddr)); ai->ai_addr = (struct sockaddr *)(ai + 1); ai->ai_addrlen = sizeof(*sunaddr); ai->ai_family = AF_UNIX; @@ -4998,19 +5080,19 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset, u_int *display_numberp, int **chanids) { Channel *nc = NULL; - int display_number, sock; - u_short port; + int display_number, sock, port; struct addrinfo hints, *ai, *aitop; char strport[NI_MAXSERV]; int gaierr, n, num_socks = 0, socks[NUM_SOCKS]; - if (chanids == NULL) + if (chanids == NULL || x11_display_offset < 0 || + x11_display_offset > UINT16_MAX - X11_BASE_PORT - MAX_DISPLAYS) return -1; for (display_number = x11_display_offset; - display_number < MAX_DISPLAYS; + display_number < x11_display_offset + MAX_DISPLAYS; display_number++) { - port = 6000 + display_number; + port = X11_BASE_PORT + display_number; memset(&hints, 0, sizeof(hints)); hints.ai_family = ssh->chanctxt->IPv4or6; hints.ai_flags = x11_use_localhost ? 0: AI_PASSIVE; @@ -5063,7 +5145,7 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset, if (num_socks > 0) break; } - if (display_number >= MAX_DISPLAYS) { + if (display_number >= x11_display_offset + MAX_DISPLAYS) { error("Failed to allocate internet-domain X11 display socket."); return -1; } @@ -5131,7 +5213,7 @@ is_path_to_xsocket(const char *display, char *path, size_t pathlen) struct stat sbuf; if (strlcpy(path, display, pathlen) >= pathlen) { - error("%s: display path too long", __func__); + error_f("display path too long"); return 0; } if (display[0] != '/') @@ -5226,7 +5308,8 @@ x11_connect_display(struct ssh *ssh) * buf now contains the host name. But first we parse the * display number. */ - if (sscanf(cp + 1, "%u", &display_number) != 1) { + if (sscanf(cp + 1, "%u", &display_number) != 1 || + display_number > UINT16_MAX - X11_BASE_PORT) { error("Could not parse display number from DISPLAY: %.100s", display); return -1; @@ -5236,7 +5319,7 @@ x11_connect_display(struct ssh *ssh) memset(&hints, 0, sizeof(hints)); hints.ai_family = ssh->chanctxt->IPv4or6; hints.ai_socktype = SOCK_STREAM; - snprintf(strport, sizeof strport, "%u", 6000 + display_number); + snprintf(strport, sizeof strport, "%u", X11_BASE_PORT + display_number); if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) { error("%.100s: unknown host. (%s)", buf, ssh_gai_strerror(gaierr)); @@ -5252,7 +5335,7 @@ x11_connect_display(struct ssh *ssh) /* Connect it to the display. */ if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) { debug2("connect %.100s port %u: %.100s", buf, - 6000 + display_number, strerror(errno)); + X11_BASE_PORT + display_number, strerror(errno)); close(sock); continue; } @@ -5262,7 +5345,7 @@ x11_connect_display(struct ssh *ssh) freeaddrinfo(aitop); if (!ai) { error("connect %.100s port %u: %.100s", buf, - 6000 + display_number, strerror(errno)); + X11_BASE_PORT + display_number, strerror(errno)); return -1; } set_nodelay(sock); @@ -5336,3 +5419,23 @@ x11_request_forwarding_with_spoofing(struct ssh *ssh, int client_session_id, fatal_fr(r, "send x11-req"); free(new_data); } + +/* + * Returns whether an x11 channel was used recently (less than a second ago) + */ +int +x11_channel_used_recently(struct ssh *ssh) { + u_int i; + Channel *c; + time_t lastused = 0; + + for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { + c = ssh->chanctxt->channels[i]; + if (c == NULL || c->ctype == NULL || c->lastused == 0 || + strcmp(c->ctype, "x11-connection") != 0) + continue; + if (c->lastused > lastused) + lastused = c->lastused; + } + return lastused != 0 && monotime() <= lastused + 1; +} diff --git a/channels.h b/channels.h index 3ac5e83..2fcf9f8 100644 --- a/channels.h +++ b/channels.h @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.157 2024/07/25 22:40:08 djm Exp $ */ +/* $OpenBSD: channels.h,v 1.164 2026/03/05 05:40:35 djm Exp $ */ /* * Author: Tatu Ylonen @@ -82,6 +82,10 @@ #define FORWARD_ADM 0x100 #define FORWARD_USER 0x101 +/* default pattern-lists used to classify channel types as bulk */ +#define CHANNEL_BULK_TTY "" +#define CHANNEL_BULK_NOTTY "direct-*,forwarded-*,tun-*,x11-*,session*" + struct ssh; struct Channel; typedef struct Channel Channel; @@ -141,6 +145,7 @@ struct Channel { int ctl_chan; /* control channel (multiplexed connections) */ uint32_t ctl_child_id; /* child session for mux controllers */ int have_ctl_child_id;/* non-zero if ctl_child_id is valid */ + int remote_has_tty; /* remote side has a tty */ int isatty; /* rfd is a tty */ #ifdef _AIX int wfd_isatty; /* wfd is a tty */ @@ -176,10 +181,12 @@ struct Channel { u_int local_consumed; u_int local_maxpacket; int extended_usage; + int agent_new; /* For agent listeners, use RFC XXX reqests */ int single_connection; char *ctype; /* const type - NB. not freed on channel_free */ char *xctype; /* extended type */ + int bulk; /* channel is non-interactive */ /* callback */ channel_open_fn *open_confirm; @@ -277,8 +284,9 @@ struct Channel { c->efd != -1 && (!(c->flags & (CHAN_EOF_RCVD|CHAN_CLOSE_RCVD)) || \ sshbuf_len(c->extended) > 0)) -/* Add channel management structures to SSH transport instance */ +/* Add/remove channel management structures to/from SSH transport instance */ void channel_init_channels(struct ssh *ssh); +void channel_free_channels(struct ssh *ssh); /* channel management */ @@ -289,6 +297,7 @@ Channel *channel_new(struct ssh *, char *, int, int, int, int, u_int, u_int, int, const char *, int); void channel_set_fds(struct ssh *, int, int, int, int, int, int, int, u_int); +void channel_set_tty(struct ssh *, Channel *); void channel_free(struct ssh *, Channel *); void channel_free_all(struct ssh *); void channel_stop_listening(struct ssh *); @@ -296,7 +305,7 @@ void channel_force_close(struct ssh *, Channel *, int); void channel_set_xtype(struct ssh *, int, const char *); void channel_send_open(struct ssh *, int); -void channel_request_start(struct ssh *, int, char *, int); +void channel_request_start(struct ssh *, int, const char *, int); void channel_register_cleanup(struct ssh *, int, channel_callback_fn *, int); void channel_register_open_confirm(struct ssh *, int, @@ -308,6 +317,7 @@ void channel_register_status_confirm(struct ssh *, int, void channel_cancel_cleanup(struct ssh *, int); int channel_close_fd(struct ssh *, Channel *, int *); void channel_send_window_changes(struct ssh *); +int channel_has_bulk(struct ssh *); /* channel inactivity timeouts */ void channel_add_timeout(struct ssh *, const char *, int); @@ -316,18 +326,18 @@ void channel_clear_timeouts(struct ssh *); /* mux proxy support */ int channel_proxy_downstream(struct ssh *, Channel *mc); -int channel_proxy_upstream(Channel *, int, u_int32_t, struct ssh *); +int channel_proxy_upstream(Channel *, int, uint32_t, struct ssh *); /* protocol handler */ -int channel_input_data(int, u_int32_t, struct ssh *); -int channel_input_extended_data(int, u_int32_t, struct ssh *); -int channel_input_ieof(int, u_int32_t, struct ssh *); -int channel_input_oclose(int, u_int32_t, struct ssh *); -int channel_input_open_confirmation(int, u_int32_t, struct ssh *); -int channel_input_open_failure(int, u_int32_t, struct ssh *); -int channel_input_window_adjust(int, u_int32_t, struct ssh *); -int channel_input_status_confirm(int, u_int32_t, struct ssh *); +int channel_input_data(int, uint32_t, struct ssh *); +int channel_input_extended_data(int, uint32_t, struct ssh *); +int channel_input_ieof(int, uint32_t, struct ssh *); +int channel_input_oclose(int, uint32_t, struct ssh *); +int channel_input_open_confirmation(int, uint32_t, struct ssh *); +int channel_input_open_failure(int, uint32_t, struct ssh *); +int channel_input_window_adjust(int, uint32_t, struct ssh *); +int channel_input_status_confirm(int, uint32_t, struct ssh *); /* file descriptor handling (read/write) */ struct pollfd; @@ -344,6 +354,7 @@ int channel_still_open(struct ssh *); int channel_tty_open(struct ssh *); const char *channel_format_extended_usage(const Channel *); char *channel_open_message(struct ssh *); +void channel_report_open(struct ssh *, int); int channel_find_open(struct ssh *); /* tcp forwarding */ @@ -382,12 +393,16 @@ int x11_connect_display(struct ssh *); int x11_create_display_inet(struct ssh *, int, int, int, u_int *, int **); void x11_request_forwarding_with_spoofing(struct ssh *, int, const char *, const char *, const char *, int); +int x11_channel_used_recently(struct ssh *ssh); /* channel close */ int chan_is_dead(struct ssh *, Channel *, int); void chan_mark_dead(struct ssh *, Channel *); +/* agent forwarding */ +void client_channel_reqest_agent_forwarding(struct ssh *, int); + /* channel events */ void chan_rcvd_oclose(struct ssh *, Channel *); diff --git a/cipher-aesctr.c b/cipher-aesctr.c index eed95c3..2a8d446 100644 --- a/cipher-aesctr.c +++ b/cipher-aesctr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cipher-aesctr.c,v 1.2 2015/01/14 10:24:42 markus Exp $ */ +/* $OpenBSD: cipher-aesctr.c,v 1.3 2026/02/09 22:15:45 dtucker Exp $ */ /* * Copyright (c) 2003 Markus Friedl. All rights reserved. * @@ -17,11 +17,11 @@ #include "includes.h" +#ifndef WITH_OPENSSL + #include #include -#ifndef WITH_OPENSSL - #include "cipher-aesctr.h" /* diff --git a/cipher-chachapoly-libcrypto.c b/cipher-chachapoly-libcrypto.c index e8d20c2..73214e6 100644 --- a/cipher-chachapoly-libcrypto.c +++ b/cipher-chachapoly-libcrypto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cipher-chachapoly-libcrypto.c,v 1.2 2023/07/17 05:26:38 djm Exp $ */ +/* $OpenBSD: cipher-chachapoly-libcrypto.c,v 1.3 2026/02/14 00:18:34 jsg Exp $ */ /* * Copyright (c) 2013 Damien Miller * @@ -23,13 +23,11 @@ #if defined(HAVE_EVP_CHACHA20) && !defined(HAVE_BROKEN_CHACHA20) #include -#include /* needed for log.h */ #include #include /* needed for misc.h */ #include -#include "log.h" #include "sshbuf.h" #include "ssherr.h" #include "cipher-chachapoly.h" diff --git a/cipher.c b/cipher.c index 7d6e7d8..f770e66 100644 --- a/cipher.c +++ b/cipher.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cipher.c,v 1.123 2024/08/23 04:51:00 deraadt Exp $ */ +/* $OpenBSD: cipher.c,v 1.126 2026/02/14 00:18:34 jsg Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -47,7 +47,6 @@ #include "misc.h" #include "sshbuf.h" #include "ssherr.h" -#include "digest.h" #include "openbsd-compat/openssl-compat.h" @@ -116,25 +115,16 @@ static const struct sshcipher ciphers[] = { char * cipher_alg_list(char sep, int auth_only) { - char *tmp, *ret = NULL; - size_t nlen, rlen = 0; + char *ret = NULL; const struct sshcipher *c; + char sep_str[2] = {sep, '\0'}; for (c = ciphers; c->name != NULL; c++) { if ((c->flags & CFLAG_INTERNAL) != 0) continue; if (auth_only && c->auth_len == 0) continue; - if (ret != NULL) - ret[rlen++] = sep; - nlen = strlen(c->name); - if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) { - free(ret); - return NULL; - } - ret = tmp; - memcpy(ret + rlen, c->name, nlen + 1); - rlen += nlen; + xextendf(&ret, sep_str, "%s", c->name); } return ret; } @@ -298,8 +288,8 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher, goto out; } if (cipher_authlen(cipher) && - !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, - -1, (u_char *)iv)) { + EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, + -1, (u_char *)iv) <= 0) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } @@ -369,13 +359,13 @@ cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest, if (authlen != cipher_authlen(cc->cipher)) return SSH_ERR_INVALID_ARGUMENT; /* increment IV */ - if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, - 1, lastiv)) + if (EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, + 1, lastiv) <= 0) return SSH_ERR_LIBCRYPTO_ERROR; /* set tag on decryption */ if (!cc->encrypt && - !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_TAG, - authlen, (u_char *)src + aadlen + len)) + EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_TAG, + authlen, (u_char *)src + aadlen + len) <= 0) return SSH_ERR_LIBCRYPTO_ERROR; } if (aadlen) { @@ -395,8 +385,8 @@ cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest, return cc->encrypt ? SSH_ERR_LIBCRYPTO_ERROR : SSH_ERR_MAC_INVALID; if (cc->encrypt && - !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_GET_TAG, - authlen, dest + aadlen + len)) + EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_GET_TAG, + authlen, dest + aadlen + len) <= 0) return SSH_ERR_LIBCRYPTO_ERROR; } return 0; @@ -465,10 +455,10 @@ cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, size_t len) if ((size_t)evplen != len) return SSH_ERR_INVALID_ARGUMENT; if (cipher_authlen(c)) { - if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, - len, iv)) + if (EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, len, + iv) <= 0) return SSH_ERR_LIBCRYPTO_ERROR; - } else if (!EVP_CIPHER_CTX_get_iv(cc->evp, iv, len)) + } else if (EVP_CIPHER_CTX_get_iv(cc->evp, iv, len) <= 0) return SSH_ERR_LIBCRYPTO_ERROR; #endif return 0; @@ -495,8 +485,8 @@ cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv, size_t len) return SSH_ERR_INVALID_ARGUMENT; if (cipher_authlen(c)) { /* XXX iv arg is const, but EVP_CIPHER_CTX_ctrl isn't */ - if (!EVP_CIPHER_CTX_ctrl(cc->evp, - EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv)) + if (EVP_CIPHER_CTX_ctrl(cc->evp, + EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv) <= 0) return SSH_ERR_LIBCRYPTO_ERROR; } else if (!EVP_CIPHER_CTX_set_iv(cc->evp, iv, evplen)) return SSH_ERR_LIBCRYPTO_ERROR; diff --git a/clientloop.c b/clientloop.c index 8ed8b1c..6a0e7b6 100644 --- a/clientloop.c +++ b/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.408 2024/07/01 04:31:17 djm Exp $ */ +/* $OpenBSD: clientloop.c,v 1.422 2026/03/05 05:40:35 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -63,33 +63,22 @@ #include #include -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef HAVE_SYS_TIME_H -# include -#endif -#include +#include +#include +#include #include #include -#ifdef HAVE_PATHS_H #include -#endif -#ifdef HAVE_POLL_H #include -#endif #include #include #include #include #include -#include -#include #include #include -#include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "ssh.h" #include "ssh2.h" @@ -99,9 +88,7 @@ #include "channels.h" #include "dispatch.h" #include "sshkey.h" -#include "cipher.h" #include "kex.h" -#include "myproposal.h" #include "log.h" #include "misc.h" #include "readconf.h" @@ -111,7 +98,6 @@ #include "atomicio.h" #include "sshpty.h" #include "match.h" -#include "msg.h" #include "ssherr.h" #include "hostfile.h" @@ -147,7 +133,8 @@ extern char *forward_agent_sock_path; * because this is updated in a signal handler. */ static volatile sig_atomic_t received_window_change_signal = 0; -static volatile sig_atomic_t received_signal = 0; +static volatile sig_atomic_t siginfo_received = 0; +static volatile sig_atomic_t received_signal = 0; /* exit signals */ /* Time when backgrounded control master using ControlPersist should exit */ static time_t control_persist_exit_time = 0; @@ -224,6 +211,15 @@ window_change_handler(int sig) received_window_change_signal = 1; } +#ifdef SIGINFO +/* Signal handler for SIGINFO */ +static void +siginfo_handler(int sig) +{ + siginfo_received = 1; +} +#endif + /* * Signal handler for signals that cause the program to terminate. These * signals must be trapped to restore terminal modes. @@ -433,7 +429,7 @@ client_x11_get_proto(struct ssh *ssh, const char *display, * for the local connection. */ if (!got_data) { - u_int8_t rnd[16]; + uint8_t rnd[16]; u_int i; logit("Warning: No xauth data; " @@ -467,7 +463,7 @@ client_check_window_change(struct ssh *ssh) } static int -client_global_request_reply(int type, u_int32_t seq, struct ssh *ssh) +client_global_request_reply(int type, uint32_t seq, struct ssh *ssh) { struct global_confirm *gc; @@ -659,9 +655,10 @@ obfuscate_keystroke_timing(struct ssh *ssh, struct timespec *timeout, if (just_started) return 1; - /* Don't arm output fd for poll until the timing interval has elapsed */ + /* Don't arm output fd for poll until the timing interval has elapsed... */ if (timespeccmp(&now, &next_interval, <)) - return 0; + /* ...unless there's x11 communication happening */ + return x11_channel_used_recently(ssh); /* Calculate number of intervals missed since the last check */ n = (now.tv_sec - next_interval.tv_sec) * 1000LL * 1000 * 1000; @@ -939,7 +936,7 @@ client_repledge(void) /* Might be able to tighten pledge now that session is established */ if (options.control_master || options.control_path != NULL || options.forward_x11 || options.fork_after_authentication || - can_update_hostkeys() || + options.pkcs11_provider != NULL || can_update_hostkeys() || (session_ident != -1 && !session_setup_complete)) { /* Can't tighten */ return; @@ -964,11 +961,11 @@ client_repledge(void) } else if (options.forward_agent != 0) { /* agent forwarding needs to open $SSH_AUTH_SOCK at will */ debug("pledge: agent"); - if (pledge("stdio unix proc tty", NULL) == -1) + if (pledge(PLEDGE_EXTRA_INET "stdio unix proc tty", NULL) == -1) fatal_f("pledge(): %s", strerror(errno)); } else { debug("pledge: fork"); - if (pledge("stdio proc tty", NULL) == -1) + if (pledge(PLEDGE_EXTRA_INET "stdio proc tty", NULL) == -1) fatal_f("pledge(): %s", strerror(errno)); } /* XXX further things to do: @@ -1122,6 +1119,7 @@ static struct escape_help_text esc_txt[] = { SUPPRESS_MUXCLIENT}, {"B", "send a BREAK to the remote system", SUPPRESS_NEVER}, {"C", "open a command line", SUPPRESS_MUXCLIENT|SUPPRESS_NOCMDLINE}, + {"I", "show connection information", SUPPRESS_NEVER}, {"R", "request rekey", SUPPRESS_NEVER}, {"V/v", "decrease/increase verbosity (LogLevel)", SUPPRESS_MUXCLIENT}, {"^Z", "suspend ssh", SUPPRESS_MUXCLIENT}, @@ -1244,6 +1242,16 @@ process_escapes(struct ssh *ssh, Channel *c, fatal_fr(r, "send packet"); continue; + case 'I': + if ((r = sshbuf_putf(berr, "%cI\r\n", + efc->escape_char)) != 0) + fatal_fr(r, "sshbuf_putf"); + s = connection_info_message(ssh); + if ((r = sshbuf_put(berr, s, strlen(s))) != 0) + fatal_fr(r, "sshbuf_put"); + free(s); + continue; + case 'R': if (ssh->compat & SSH_BUG_NOREKEY) logit("Server does not " @@ -1446,15 +1454,17 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, struct pollfd *pfd = NULL; u_int npfd_alloc = 0, npfd_active = 0; double start_time, total_time; - int channel_did_enqueue = 0, r; - u_int64_t ibytes, obytes; + int interactive = -1, channel_did_enqueue = 0, r; + uint64_t ibytes, obytes; int conn_in_ready, conn_out_ready; sigset_t bsigset, osigset; debug("Entering interactive session."); session_ident = ssh2_chan_id; - if (options.control_master && + if (options.pkcs11_provider != NULL) + debug("pledge: disabled (PKCS11Provider active)"); + else if (options.control_master && !option_clear_or_none(options.control_path)) { debug("pledge: id"); if (pledge("stdio rpath wpath cpath unix inet dns recvfd sendfd proc exec id tty", @@ -1513,6 +1523,9 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, if (ssh_signal(SIGTERM, SIG_IGN) != SIG_IGN) ssh_signal(SIGTERM, signal_handler); ssh_signal(SIGWINCH, window_change_handler); +#ifdef SIGINFO + ssh_signal(SIGINFO, siginfo_handler); +#endif if (have_pty) enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); @@ -1537,6 +1550,10 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, sigaddset(&bsigset, SIGQUIT) == -1 || sigaddset(&bsigset, SIGTERM) == -1) error_f("bsigset setup: %s", strerror(errno)); +#ifdef SIGINFO + if (sigaddset(&bsigset, SIGINFO) == -1) + error_f("bsigset setup: %s", strerror(errno)); +#endif /* Main loop of the client for the interactive session mode. */ while (!quit_pending) { @@ -1576,6 +1593,10 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, */ if (sigprocmask(SIG_BLOCK, &bsigset, &osigset) == -1) error_f("bsigset sigprocmask: %s", strerror(errno)); + if (siginfo_received) { + siginfo_received = 0; + channel_report_open(ssh, SYSLOG_LEVEL_INFO); + } if (quit_pending) break; client_wait_until_can_do_something(ssh, &pfd, &npfd_alloc, @@ -1606,6 +1627,12 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, * sender. */ if (conn_out_ready) { + if (interactive != !channel_has_bulk(ssh)) { + interactive = !channel_has_bulk(ssh); + debug2_f("session QoS is now %s", interactive ? + "interactive" : "non-interactive"); + ssh_packet_set_interactive(ssh, interactive); + } if ((r = ssh_packet_write_poll(ssh)) != 0) { sshpkt_fatal(ssh, r, "%s: ssh_packet_write_poll", __func__); @@ -1848,7 +1875,7 @@ client_request_tun_fwd(struct ssh *ssh, int tun_mode, char *ifname = NULL; if (tun_mode == SSH_TUNMODE_NO) - return 0; + return NULL; debug("Requesting tun unit %d in mode %d", local_tun, tun_mode); @@ -1887,7 +1914,7 @@ client_request_tun_fwd(struct ssh *ssh, int tun_mode, /* XXXX move to generic input handler */ static int -client_input_channel_open(int type, u_int32_t seq, struct ssh *ssh) +client_input_channel_open(int type, uint32_t seq, struct ssh *ssh) { Channel *c = NULL; char *ctype = NULL; @@ -1912,7 +1939,8 @@ client_input_channel_open(int type, u_int32_t seq, struct ssh *ssh) c = client_request_forwarded_streamlocal(ssh, ctype, rchan); } else if (strcmp(ctype, "x11") == 0) { c = client_request_x11(ssh, ctype, rchan); - } else if (strcmp(ctype, "auth-agent@openssh.com") == 0) { + } else if (strcmp(ctype, "auth-agent@openssh.com") == 0 || + strcmp(ctype, "agent-connect") == 0) { c = client_request_agent(ssh, ctype, rchan); } if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) { @@ -1949,7 +1977,7 @@ client_input_channel_open(int type, u_int32_t seq, struct ssh *ssh) } static int -client_input_channel_req(int type, u_int32_t seq, struct ssh *ssh) +client_input_channel_req(int type, uint32_t seq, struct ssh *ssh) { Channel *c = NULL; char *rtype = NULL; @@ -2327,7 +2355,7 @@ update_known_hosts(struct hostkeys_update_ctx *ctx) static void client_global_hostkeys_prove_confirm(struct ssh *ssh, int type, - u_int32_t seq, void *_ctx) + uint32_t seq, void *_ctx) { struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx; size_t i, ndone; @@ -2419,6 +2447,7 @@ client_global_hostkeys_prove_confirm(struct ssh *ssh, int type, /* Make the edits to known_hosts */ update_known_hosts(ctx); out: + sshbuf_free(signdata); hostkeys_update_ctx_free(ctx); hostkeys_update_complete = 1; client_repledge(); @@ -2636,7 +2665,7 @@ client_input_hostkeys(struct ssh *ssh) } static int -client_input_global_request(int type, u_int32_t seq, struct ssh *ssh) +client_input_global_request(int type, uint32_t seq, struct ssh *ssh) { char *rtype; u_char want_reply; @@ -2690,9 +2719,6 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem, if ((c = channel_lookup(ssh, id)) == NULL) fatal_f("channel %d: unknown channel", id); - ssh_packet_set_interactive(ssh, want_tty, - options.ip_qos_interactive, options.ip_qos_bulk); - if (want_tty) { struct winsize ws; @@ -2788,6 +2814,20 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem, client_repledge(); } +void +client_channel_reqest_agent_forwarding(struct ssh *ssh, int id) +{ + const char *req = "auth-agent-req@openssh.com"; + int r; + + if (ssh->kex != NULL && (ssh->kex->flags & KEX_HAS_NEWAGENT) != 0) + req = "agent-req"; /* XXX RFC XXX */ + debug("Requesting agent forwarding on channel %d via %s", id, req); + channel_request_start(ssh, id, req, 0); + if ((r = sshpkt_send(ssh)) != 0) + fatal_fr(r, "send"); +} + static void client_init_dispatch(struct ssh *ssh) { diff --git a/clientloop.h b/clientloop.h index 4bc7bcd..ed3c54f 100644 --- a/clientloop.h +++ b/clientloop.h @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.h,v 1.38 2024/05/17 06:42:04 jsg Exp $ */ +/* $OpenBSD: clientloop.h,v 1.41 2026/03/03 09:57:25 dtucker Exp $ */ /* * Author: Tatu Ylonen @@ -55,7 +55,7 @@ void client_filter_cleanup(struct ssh *, int, void *); int client_simple_escape_filter(struct ssh *, Channel *, char *, int); /* Global request confirmation callbacks */ -typedef void global_confirm_cb(struct ssh *, int, u_int32_t, void *); +typedef void global_confirm_cb(struct ssh *, int, uint32_t, void *); void client_register_global_confirm(global_confirm_cb *, void *); /* Channel request confirmation callbacks */ @@ -75,6 +75,8 @@ void client_expect_confirm(struct ssh *, int, const char *, #define SSHMUX_COMMAND_STOP 6 /* Disable mux but not conn */ #define SSHMUX_COMMAND_CANCEL_FWD 7 /* Cancel forwarding(s) */ #define SSHMUX_COMMAND_PROXY 8 /* Open new connection */ +#define SSHMUX_COMMAND_CONNINFO 9 /* Show connection information */ +#define SSHMUX_COMMAND_CHANINFO 10 /* Show channels information */ void muxserver_listen(struct ssh *); int muxclient(const char *); diff --git a/compat.c b/compat.c index b59f0bf..4cc7ca6 100644 --- a/compat.c +++ b/compat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: compat.c,v 1.126 2023/03/06 12:14:48 dtucker Exp $ */ +/* $OpenBSD: compat.c,v 1.128 2026/03/02 02:40:15 djm Exp $ */ /* * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. * @@ -27,8 +27,8 @@ #include +#include #include -#include #include #include "xmalloc.h" @@ -44,7 +44,7 @@ compat_banner(struct ssh *ssh, const char *version) int i; static struct { char *pat; - int bugs; + uint32_t bugs; } check[] = { { "OpenSSH_2.*," "OpenSSH_3.0*," diff --git a/config.h.in b/config.h.in index 14bee60..4c12a6c 100644 --- a/config.h.in +++ b/config.h.in @@ -34,7 +34,7 @@ /* getline is not what we expect */ #undef BROKEN_GETLINE -/* FreeBSD glob does not do what we need */ +/* Do not use system glob */ #undef BROKEN_GLOB /* Define if you system's inet_ntoa is busted (e.g. Irix gcc issue) */ @@ -216,6 +216,9 @@ /* Have attribute nonnull */ #undef HAVE_ATTRIBUTE__NONNULL__ +/* compiler supports nonstring attribute */ +#undef HAVE_ATTRIBUTE__NONSTRING__ + /* OpenBSD's gcc has sentinel */ #undef HAVE_ATTRIBUTE__SENTINEL__ @@ -363,10 +366,26 @@ don't. */ #undef HAVE_DECL_HOWMANY +/* Define to 1 if you have the declaration of `htole64', and to 0 if you + don't. */ +#undef HAVE_DECL_HTOLE64 + /* Define to 1 if you have the declaration of `h_errno', and to 0 if you don't. */ #undef HAVE_DECL_H_ERRNO +/* Define to 1 if you have the declaration of `INFINITY', and to 0 if you + don't. */ +#undef HAVE_DECL_INFINITY + +/* Define to 1 if you have the declaration of `le32toh', and to 0 if you + don't. */ +#undef HAVE_DECL_LE32TOH + +/* Define to 1 if you have the declaration of `le64toh', and to 0 if you + don't. */ +#undef HAVE_DECL_LE64TOH + /* Define to 1 if you have the declaration of `loginfailed', and to 0 if you don't. */ #undef HAVE_DECL_LOGINFAILED @@ -395,14 +414,6 @@ don't. */ #undef HAVE_DECL_OFFSETOF -/* Define to 1 if you have the declaration of `OPENSSL_IS_BORINGSSL', and to 0 - if you don't. */ -#undef HAVE_DECL_OPENSSL_IS_BORINGSSL - -/* Define to 1 if you have the declaration of `OPENSSL_NO_DSA', and to 0 if - you don't. */ -#undef HAVE_DECL_OPENSSL_NO_DSA - /* Define to 1 if you have the declaration of `O_NONBLOCK', and to 0 if you don't. */ #undef HAVE_DECL_O_NONBLOCK @@ -439,6 +450,10 @@ don't. */ #undef HAVE_DECL__GETSHORT +/* Define to 1 if you have the declaration of `__builtin_inff', and to 0 if + you don't. */ +#undef HAVE_DECL___BUILTIN_INFF + /* Define to 1 if you have the `DES_crypt' function. */ #undef HAVE_DES_CRYPT @@ -460,12 +475,23 @@ /* Define to 1 if you have the `dlopen' function. */ #undef HAVE_DLOPEN -/* Define to 1 if you have the `DSA_generate_parameters_ex' function. */ -#undef HAVE_DSA_GENERATE_PARAMETERS_EX - /* Define to 1 if you have the `EC_KEY_METHOD_new' function. */ #undef HAVE_EC_KEY_METHOD_NEW +/* Define to 1 if you have the `EC_POINT_get_affine_coordinates' function. */ +#undef HAVE_EC_POINT_GET_AFFINE_COORDINATES + +/* Define to 1 if you have the `EC_POINT_get_affine_coordinates_GFp' function. + */ +#undef HAVE_EC_POINT_GET_AFFINE_COORDINATES_GFP + +/* Define to 1 if you have the `EC_POINT_set_affine_coordinates' function. */ +#undef HAVE_EC_POINT_SET_AFFINE_COORDINATES + +/* Define to 1 if you have the `EC_POINT_set_affine_coordinates_GFp' function. + */ +#undef HAVE_EC_POINT_SET_AFFINE_COORDINATES_GFP + /* Define to 1 if you have the header file. */ #undef HAVE_ELF_H @@ -631,6 +657,9 @@ /* Define to 1 if the system has the type `fsfilcnt_t'. */ #undef HAVE_FSFILCNT_T +/* Define to 1 if you have the `fstatat' function. */ +#undef HAVE_FSTATAT + /* Define to 1 if you have the `fstatfs' function. */ #undef HAVE_FSTATFS @@ -968,6 +997,9 @@ /* Define to 1 if you have the `mkdtemp' function. */ #undef HAVE_MKDTEMP +/* Define to 1 if you have the `mmap' function. */ +#undef HAVE_MMAP + /* define if you have mode_t data type */ #undef HAVE_MODE_T @@ -998,6 +1030,12 @@ /* Define to 1 if you have the `ngetaddrinfo' function. */ #undef HAVE_NGETADDRINFO +/* Define to 1 if you have the `nlist' function. */ +#undef HAVE_NLIST + +/* Define to 1 if you have the header file. */ +#undef HAVE_NLIST_H + /* Define to 1 if you have the `nl_langinfo' function. */ #undef HAVE_NL_LANGINFO @@ -1017,9 +1055,6 @@ /* Define to 1 if you have the `openpty' function. */ #undef HAVE_OPENPTY -/* as a macro */ -#undef HAVE_OPENSSL_ADD_ALL_ALGORITHMS - /* Define to 1 if you have the `OpenSSL_version' function. */ #undef HAVE_OPENSSL_VERSION @@ -1357,6 +1392,9 @@ /* define if you have struct addrinfo data type */ #undef HAVE_STRUCT_ADDRINFO +/* Define to 1 if `d_type' is a member of `struct dirent'. */ +#undef HAVE_STRUCT_DIRENT_D_TYPE + /* define if you have struct in6_addr data type */ #undef HAVE_STRUCT_IN6_ADDR @@ -1576,12 +1614,18 @@ /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H +/* Define to 1 if you have the `unlinkat' function. */ +#undef HAVE_UNLINKAT + /* Define to 1 if you have the `unsetenv' function. */ #undef HAVE_UNSETENV /* Define to 1 if the system has the type `unsigned long long'. */ #undef HAVE_UNSIGNED_LONG_LONG +/* Define to 1 if you have the `unveil' function. */ +#undef HAVE_UNVEIL + /* Define to 1 if you have the `updwtmp' function. */ #undef HAVE_UPDWTMP @@ -1712,6 +1756,9 @@ EOPNOTSUPP. */ #undef LINK_OPNOTSUPP_ERRNO +/* Lock all memory to protect sshd against Linux kcompactd */ +#undef LINUX_MEMLOCK_ONFAULT + /* Adjust Linux out-of-memory killer */ #undef LINUX_OOM_ADJUST @@ -1736,6 +1783,9 @@ /* Set this to your mail directory if you do not have _PATH_MAILDIR */ #undef MAIL_DIRECTORY +/* Define if your compiler lacks __builtin_popcount */ +#undef MISSING_BUILTIN_POPCOUNT + /* Need setpgrp to for controlling tty */ #undef NEED_SETPGRP @@ -1809,6 +1859,12 @@ /* System dirs owned by bin (uid 2) */ #undef PLATFORM_SYS_DIR_UID +/* need inet in pledge for setsockopt IP_TOS */ +#undef PLEDGE_EXTRA_INET + +/* Define if poll 2nd arg is ulong */ +#undef POLL_NFDS_T_ULONG + /* Port number of PRNGD/EGD random number socket */ #undef PRNGD_PORT @@ -1827,9 +1883,6 @@ /* no privsep sandboxing */ #undef SANDBOX_NULL -/* Sandbox using pledge(2) */ -#undef SANDBOX_PLEDGE - /* Sandbox using setrlimit(2) */ #undef SANDBOX_RLIMIT @@ -1845,9 +1898,6 @@ /* Sandbox using Solaris/Illumos privileges */ #undef SANDBOX_SOLARIS -/* Sandbox using systrace(4) */ -#undef SANDBOX_SYSTRACE - /* Specify the system call convention in use */ #undef SECCOMP_AUDIT_ARCH @@ -1885,9 +1935,6 @@ /* sshd PAM service name */ #undef SSHD_PAM_SERVICE -/* Define if pam_chauthtok wants real uid set to the unpriv'ed user */ -#undef SSHPAM_CHAUTHTOK_NEEDS_RUID - /* Use audit debugging module */ #undef SSH_AUDIT_EVENTS @@ -1971,6 +2018,9 @@ /* Define if you have Solaris projects */ #undef USE_SOLARIS_PROJECTS +/* Use libwtmpdb for sshd */ +#undef USE_WTMPDB + /* compiler variable declarations after code */ #undef VARIABLE_DECLARATION_AFTER_CODE @@ -1983,9 +2033,6 @@ /* Define if you want to enable AIX4's authenticate function */ #undef WITH_AIXAUTHENTICATE -/* DSA keys explicitly enabled */ -#undef WITH_DSA - /* Define if you have/want arrays (cluster-wide session management, not C arrays) */ #undef WITH_IRIX_ARRAY diff --git a/configure b/configure index b4d33b7..e2174fc 100755 --- a/configure +++ b/configure @@ -650,8 +650,10 @@ ac_includes_default="\ ac_header_c_list= ac_subst_vars='LTLIBOBJS +COMPATINCLUDES CFLAGS_NOPIE LDFLAGS_NOPIE +TMUX DROPBEARCONVERT DROPBEARKEY DBCLIENT @@ -678,14 +680,17 @@ GSSLIBS KRB5CONF SSHDLIBS SSH_PRIVSEP_USER +SK_STANDALONE LIBFIDO2 SK_DUMMY_LIBRARY OPENSSL_BIN openssl_bin PICFLAG +LIBWTMPDB LIBEDIT LDNSCONFIG LIBOBJS +TESTLIBS LD PATH_PASSWD_PROG STARTUP_SCRIPT_SHELL @@ -784,6 +789,7 @@ with_ldflags with_ldflags_after with_libs with_Werror +with_linux_memlock_onfault with_solaris_contracts with_solaris_projects with_solaris_privs @@ -792,12 +798,13 @@ with_zlib with_zlib_version_check with_ldns with_libedit +with_wtmpdb with_audit with_pie enable_pkcs11 enable_security_key with_security_key_builtin -enable_dsa_keys +with_security_key_standalone with_ssl_dir with_openssl_header_check with_ssl_engine @@ -1467,7 +1474,6 @@ Optional Features: --disable-largefile omit support for large files --disable-pkcs11 disable PKCS#11 support code [no] --disable-security-key disable U2F/FIDO support code no - --enable-dsa-keys enable DSA key support no --disable-strip Disable calling strip(1) on install --disable-etc-default-login Disable using PATH from /etc/default/login no --disable-fd-passing disable file descriptor passsing no @@ -1495,6 +1501,7 @@ Optional Packages: --with-ldflags-after Specify additional flags to pass to linker after configure --with-libs Specify additional libraries to link with --with-Werror Build main code with -Werror + --with-linux-memlock-onfault Enables memory locking on Linux --with-solaris-contracts Enable Solaris process contracts (experimental) --with-solaris-projects Enable Solaris projects (experimental) --with-solaris-privs Enable Solaris/Illumos privileges (experimental) @@ -1503,9 +1510,11 @@ Optional Packages: --without-zlib-version-check Disable zlib version check --with-ldns[=PATH] Use ldns for DNSSEC support (optionally in PATH) --with-libedit[=PATH] Enable libedit support for sftp + --with-wtmpdb[=PATH] Enable wtmpdb support for sshd --with-audit=module Enable audit support (modules=debug,bsm,linux) --with-pie Build Position Independent Executables if possible --with-security-key-builtin include builtin U2F/FIDO support + --with-security-key-standalone build standalone sk-libfido2 SecurityKeyProvider --with-ssl-dir=PATH Specify path to OpenSSL installation --without-openssl-header-check Disable OpenSSL version consistency check --with-ssl-engine Enable OpenSSL (hardware) ENGINE support @@ -1514,7 +1523,7 @@ Optional Packages: --with-pam Enable PAM support --with-pam-service=name Specify PAM service name --with-privsep-user=user Specify non-privileged user for privilege separation - --with-sandbox=style Specify privilege separation sandbox (no, capsicum, darwin, rlimit, seccomp_filter, systrace, pledge) + --with-sandbox=style Specify privilege separation sandbox (no, capsicum, darwin, rlimit, seccomp_filter) --with-selinux Enable SELinux support --with-kerberos5=PATH Enable Kerberos 5 support --with-privsep-path=xxx Path for privilege separation chroot (default=/var/empty) @@ -1935,122 +1944,122 @@ printf "%s\n" "$ac_res" >&6; } } # ac_fn_c_check_func -# ac_fn_c_check_type LINENO TYPE VAR INCLUDES -# ------------------------------------------- -# Tests whether TYPE exists after having included INCLUDES, setting cache -# variable VAR accordingly. -ac_fn_c_check_type () +# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES +# ---------------------------------------------------- +# Tries to find if the field MEMBER exists in type AGGR, after including +# INCLUDES, setting cache variable VAR accordingly. +ac_fn_c_check_member () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -printf %s "checking for $2... " >&6; } -if eval test \${$3+y} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 +printf %s "checking for $2.$3... " >&6; } +if eval test \${$4+y} then : printf %s "(cached) " >&6 else $as_nop - eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -$4 +$5 int main (void) { -if (sizeof ($2)) - return 0; +static $2 ac_aggr; +if (ac_aggr.$3) +return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : + eval "$4=yes" +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -$4 +$5 int main (void) { -if (sizeof (($2))) - return 0; +static $2 ac_aggr; +if (sizeof ac_aggr.$3) +return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : - + eval "$4=yes" else $as_nop - eval "$3=yes" + eval "$4=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -eval ac_res=\$$3 +eval ac_res=\$$4 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno -} # ac_fn_c_check_type +} # ac_fn_c_check_member -# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES -# ---------------------------------------------------- -# Tries to find if the field MEMBER exists in type AGGR, after including -# INCLUDES, setting cache variable VAR accordingly. -ac_fn_c_check_member () +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 -printf %s "checking for $2.$3... " >&6; } -if eval test \${$4+y} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +printf %s "checking for $2... " >&6; } +if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop + eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -$5 +$4 int main (void) { -static $2 ac_aggr; -if (ac_aggr.$3) -return 0; +if (sizeof ($2)) + return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : - eval "$4=yes" -else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -$5 +$4 int main (void) { -static $2 ac_aggr; -if (sizeof ac_aggr.$3) -return 0; +if (sizeof (($2))) + return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : - eval "$4=yes" + else $as_nop - eval "$4=no" + eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -eval ac_res=\$$4 +eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno -} # ac_fn_c_check_member +} # ac_fn_c_check_type # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES # -------------------------------------------- @@ -5974,16 +5983,6 @@ if test "x$ac_cv_have_decl_LONG_LONG_MAX" = xyes then : have_long_long_max=1 fi -ac_fn_check_decl "$LINENO" "SYSTR_POLICY_KILL" "ac_cv_have_decl_SYSTR_POLICY_KILL" " - #include - #include - #include - -" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_SYSTR_POLICY_KILL" = xyes -then : - have_systr_policy_kill=1 -fi ac_fn_check_decl "$LINENO" "RLIMIT_NPROC" "ac_cv_have_decl_RLIMIT_NPROC" " #include #include @@ -6119,8 +6118,14 @@ printf %s "checking clang version... " >&6; } printf "%s\n" "$CLANG_VER" >&6; } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -pipe" >&5 + ossh_cache_var=ossh_cv_cflag__pipe + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -pipe" >&5 printf %s "checking if $CC supports compile flag -pipe... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -pipe" _define_flag="" @@ -6185,14 +6190,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -6252,12 +6255,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -6266,16 +6267,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wunknown-warning-option" >&5 + ossh_cache_var=ossh_cv_cflag__Wunknown_warning_option + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wunknown-warning-option" >&5 printf %s "checking if $CC supports compile flag -Wunknown-warning-option... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wunknown-warning-option" _define_flag="" @@ -6340,14 +6351,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -6407,12 +6416,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -6421,16 +6428,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wno-error=format-truncation" >&5 + ossh_cache_var=ossh_cv_cflag__Wno_error_format_truncation + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wno-error=format-truncation" >&5 printf %s "checking if $CC supports compile flag -Wno-error=format-truncation... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wno-error=format-truncation" _define_flag="" @@ -6495,14 +6512,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -6562,12 +6577,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -6576,16 +6589,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Qunused-arguments" >&5 + ossh_cache_var=ossh_cv_cflag__Qunused_arguments + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Qunused-arguments" >&5 printf %s "checking if $CC supports compile flag -Qunused-arguments... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Qunused-arguments" _define_flag="" @@ -6650,14 +6673,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -6717,12 +6738,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -6731,16 +6750,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wall" >&5 + ossh_cache_var=ossh_cv_cflag__Wall + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wall" >&5 printf %s "checking if $CC supports compile flag -Wall... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wall" _define_flag="" @@ -6805,14 +6834,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -6872,12 +6899,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -6886,16 +6911,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wextra" >&5 + ossh_cache_var=ossh_cv_cflag__Wextra + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wextra" >&5 printf %s "checking if $CC supports compile flag -Wextra... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wextra" _define_flag="" @@ -6960,14 +6995,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -7027,12 +7060,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -7041,16 +7072,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wpointer-arith" >&5 + ossh_cache_var=ossh_cv_cflag__Wpointer_arith + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wpointer-arith" >&5 printf %s "checking if $CC supports compile flag -Wpointer-arith... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wpointer-arith" _define_flag="" @@ -7115,14 +7156,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -7182,12 +7221,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -7196,16 +7233,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wuninitialized" >&5 + ossh_cache_var=ossh_cv_cflag__Wuninitialized + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wuninitialized" >&5 printf %s "checking if $CC supports compile flag -Wuninitialized... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wuninitialized" _define_flag="" @@ -7270,14 +7317,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -7337,12 +7382,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -7351,16 +7394,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wsign-compare" >&5 + ossh_cache_var=ossh_cv_cflag__Wsign_compare + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wsign-compare" >&5 printf %s "checking if $CC supports compile flag -Wsign-compare... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wsign-compare" _define_flag="" @@ -7425,14 +7478,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -7492,12 +7543,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -7506,16 +7555,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wformat-security" >&5 + ossh_cache_var=ossh_cv_cflag__Wformat_security + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wformat-security" >&5 printf %s "checking if $CC supports compile flag -Wformat-security... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wformat-security" _define_flag="" @@ -7580,14 +7639,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -7647,12 +7704,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -7661,16 +7716,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wsizeof-pointer-memaccess" >&5 + ossh_cache_var=ossh_cv_cflag__Wsizeof_pointer_memaccess + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wsizeof-pointer-memaccess" >&5 printf %s "checking if $CC supports compile flag -Wsizeof-pointer-memaccess... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wsizeof-pointer-memaccess" _define_flag="" @@ -7735,14 +7800,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -7802,12 +7865,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -7816,16 +7877,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wpointer-sign" >&5 + ossh_cache_var=ossh_cv_cflag__Wpointer_sign + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wpointer-sign" >&5 printf %s "checking if $CC supports compile flag -Wpointer-sign... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wpointer-sign" _define_flag="-Wno-pointer-sign" @@ -7890,14 +7961,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -7957,12 +8026,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -7971,16 +8038,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wunused-parameter" >&5 + ossh_cache_var=ossh_cv_cflag__Wunused_parameter + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wunused-parameter" >&5 printf %s "checking if $CC supports compile flag -Wunused-parameter... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wunused-parameter" _define_flag="-Wno-unused-parameter" @@ -8045,14 +8122,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -8112,12 +8187,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -8126,16 +8199,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wunused-result" >&5 + ossh_cache_var=ossh_cv_cflag__Wunused_result + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wunused-result" >&5 printf %s "checking if $CC supports compile flag -Wunused-result... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wunused-result" _define_flag="-Wno-unused-result" @@ -8200,14 +8283,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -8267,12 +8348,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -8281,16 +8360,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wimplicit-fallthrough" >&5 + ossh_cache_var=ossh_cv_cflag__Wimplicit_fallthrough + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wimplicit-fallthrough" >&5 printf %s "checking if $CC supports compile flag -Wimplicit-fallthrough... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wimplicit-fallthrough" _define_flag="" @@ -8355,14 +8444,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -8422,12 +8509,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -8436,16 +8521,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wmisleading-indentation" >&5 + ossh_cache_var=ossh_cv_cflag__Wmisleading_indentation + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wmisleading-indentation" >&5 printf %s "checking if $CC supports compile flag -Wmisleading-indentation... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wmisleading-indentation" _define_flag="" @@ -8510,14 +8605,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -8577,12 +8670,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -8591,16 +8682,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wbitwise-instead-of-logical" >&5 + ossh_cache_var=ossh_cv_cflag__Wbitwise_instead_of_logical + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wbitwise-instead-of-logical" >&5 printf %s "checking if $CC supports compile flag -Wbitwise-instead-of-logical... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wbitwise-instead-of-logical" _define_flag="" @@ -8665,14 +8766,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -8732,12 +8831,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -8746,16 +8843,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -fno-strict-aliasing" >&5 + ossh_cache_var=ossh_cv_cflag__fno_strict_aliasing + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -fno-strict-aliasing" >&5 printf %s "checking if $CC supports compile flag -fno-strict-aliasing... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -fno-strict-aliasing" _define_flag="" @@ -8820,14 +8927,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -8887,12 +8992,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -8901,17 +9004,27 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } if test "x$use_toolchain_hardening" = "x1"; then { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -D_FORTIFY_SOURCE=2" >&5 + ossh_cache_var=ossh_cv_cflag__D_FORTIFY_SOURCE_2 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -D_FORTIFY_SOURCE=2" >&5 printf %s "checking if $CC supports compile flag -D_FORTIFY_SOURCE=2... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -D_FORTIFY_SOURCE=2" _define_flag="" @@ -8976,14 +9089,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -9043,12 +9154,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -9057,16 +9166,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -Wl,-z,relro" >&5 + ossh_cache_var=ossh_cv_ldflag__Wl__z_relro + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -Wl,-z,relro" >&5 printf %s "checking if $LD supports link flag -Wl,-z,relro... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $WERROR -Wl,-z,relro" _define_flag="" @@ -9131,14 +9250,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" LDFLAGS="$saved_LDFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" LDFLAGS="$saved_LDFLAGS $_define_flag" else $as_nop @@ -9199,12 +9316,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" LDFLAGS="$saved_LDFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" LDFLAGS="$saved_LDFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -9213,17 +9328,27 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" LDFLAGS="$saved_LDFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -Wl,-z,now" >&5 + ossh_cache_var=ossh_cv_ldflag__Wl__z_now + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -Wl,-z,now" >&5 printf %s "checking if $LD supports link flag -Wl,-z,now... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $WERROR -Wl,-z,now" _define_flag="" @@ -9288,14 +9413,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" LDFLAGS="$saved_LDFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" LDFLAGS="$saved_LDFLAGS $_define_flag" else $as_nop @@ -9356,12 +9479,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" LDFLAGS="$saved_LDFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" LDFLAGS="$saved_LDFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -9370,17 +9491,27 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" LDFLAGS="$saved_LDFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -Wl,-z,noexecstack" >&5 + ossh_cache_var=ossh_cv_ldflag__Wl__z_noexecstack + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -Wl,-z,noexecstack" >&5 printf %s "checking if $LD supports link flag -Wl,-z,noexecstack... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $WERROR -Wl,-z,noexecstack" _define_flag="" @@ -9445,14 +9576,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" LDFLAGS="$saved_LDFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" LDFLAGS="$saved_LDFLAGS $_define_flag" else $as_nop @@ -9513,12 +9642,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" LDFLAGS="$saved_LDFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" LDFLAGS="$saved_LDFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -9527,13 +9654,17 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" LDFLAGS="$saved_LDFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } # NB. -ftrapv expects certain support functions to be present in # the compiler library (libgcc or similar) to detect integer operations @@ -9541,8 +9672,14 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ # actually links. The test program compiled/linked includes a number # of integer operations that should exercise this. { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -ftrapv and linking succeeds" >&5 + ossh_cache_var=ossh_cv_cflag__ftrapv + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -ftrapv and linking succeeds" >&5 printf %s "checking if $CC supports compile flag -ftrapv and linking succeeds... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -ftrapv" _define_flag="" @@ -9607,14 +9744,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -9674,12 +9809,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -9688,13 +9821,17 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } # clang 15 seems to have a bug in -fzero-call-used-regs=all. See # https://bugzilla.mindrot.org/show_bug.cgi?id=3475 and @@ -9703,8 +9840,14 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ # flag at all (https://bugzilla.mindrot.org/show_bug.cgi?id=3629) case "$CLANG_VER" in apple-15*) { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -fzero-call-used-regs=used and linking succeeds" >&5 + ossh_cache_var=ossh_cv_cflag__fzero_call_used_regs_used + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -fzero-call-used-regs=used and linking succeeds" >&5 printf %s "checking if $CC supports compile flag -fzero-call-used-regs=used and linking succeeds... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -fzero-call-used-regs=used" _define_flag="" @@ -9769,14 +9912,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -9836,12 +9977,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -9850,18 +9989,28 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } ;; 17*) ;; *) { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -fzero-call-used-regs=used and linking succeeds" >&5 + ossh_cache_var=ossh_cv_cflag__fzero_call_used_regs_used + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -fzero-call-used-regs=used and linking succeeds" >&5 printf %s "checking if $CC supports compile flag -fzero-call-used-regs=used and linking succeeds... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -fzero-call-used-regs=used" _define_flag="" @@ -9926,14 +10075,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -9993,12 +10140,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -10007,18 +10152,28 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } ;; esac { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -ftrivial-auto-var-init=zero" >&5 + ossh_cache_var=ossh_cv_cflag__ftrivial_auto_var_init_zero + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -ftrivial-auto-var-init=zero" >&5 printf %s "checking if $CC supports compile flag -ftrivial-auto-var-init=zero... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -ftrivial-auto-var-init=zero" _define_flag="" @@ -10083,14 +10238,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -10150,12 +10303,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -10164,18 +10315,28 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } fi if test "x$use_retpoline" = "x1"; then { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -mretpoline" >&5 + ossh_cache_var=ossh_cv_cflag__mretpoline + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -mretpoline" >&5 printf %s "checking if $CC supports compile flag -mretpoline... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -mretpoline" _define_flag="" @@ -10240,14 +10401,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -10307,12 +10466,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -10321,16 +10478,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } # clang { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -Wl,-z,retpolineplt" >&5 + ossh_cache_var=ossh_cv_ldflag__Wl__z_retpolineplt + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -Wl,-z,retpolineplt" >&5 printf %s "checking if $LD supports link flag -Wl,-z,retpolineplt... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $WERROR -Wl,-z,retpolineplt" _define_flag="" @@ -10395,14 +10562,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" LDFLAGS="$saved_LDFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" LDFLAGS="$saved_LDFLAGS $_define_flag" else $as_nop @@ -10463,12 +10628,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" LDFLAGS="$saved_LDFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" LDFLAGS="$saved_LDFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -10477,13 +10640,17 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" LDFLAGS="$saved_LDFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } fi @@ -10731,6 +10898,36 @@ printf "%s\n" "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +saved_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Werror" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if compiler supports __nonstring__ attribute on char arrays" >&5 +printf %s "checking if compiler supports __nonstring__ attribute on char arrays... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ + char __attribute__ ((__nonstring__)) h[5] = "hello"; return h[0]!='h'; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +printf "%s\n" "#define HAVE_ATTRIBUTE__NONSTRING__ 1" >>confdefs.h + +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +CFLAGS="$saved_CFLAGS" + if test "x$no_attrib_nonnull" != "x1" ; then printf "%s\n" "#define HAVE_ATTRIBUTE__NONNULL__ 1" >>confdefs.h @@ -10890,12 +11087,6 @@ if test "x$ac_cv_header_dirent_h" = xyes then : printf "%s\n" "#define HAVE_DIRENT_H 1" >>confdefs.h -fi -ac_fn_c_check_header_compile "$LINENO" "endian.h" "ac_cv_header_endian_h" "$ac_includes_default" -if test "x$ac_cv_header_endian_h" = xyes -then : - printf "%s\n" "#define HAVE_ENDIAN_H 1" >>confdefs.h - fi ac_fn_c_check_header_compile "$LINENO" "elf.h" "ac_cv_header_elf_h" "$ac_includes_default" if test "x$ac_cv_header_elf_h" = xyes @@ -10938,12 +11129,6 @@ if test "x$ac_cv_header_getopt_h" = xyes then : printf "%s\n" "#define HAVE_GETOPT_H 1" >>confdefs.h -fi -ac_fn_c_check_header_compile "$LINENO" "glob.h" "ac_cv_header_glob_h" "$ac_includes_default" -if test "x$ac_cv_header_glob_h" = xyes -then : - printf "%s\n" "#define HAVE_GLOB_H 1" >>confdefs.h - fi ac_fn_c_check_header_compile "$LINENO" "ia.h" "ac_cv_header_ia_h" "$ac_includes_default" if test "x$ac_cv_header_ia_h" = xyes @@ -10956,12 +11141,6 @@ if test "x$ac_cv_header_iaf_h" = xyes then : printf "%s\n" "#define HAVE_IAF_H 1" >>confdefs.h -fi -ac_fn_c_check_header_compile "$LINENO" "ifaddrs.h" "ac_cv_header_ifaddrs_h" "$ac_includes_default" -if test "x$ac_cv_header_ifaddrs_h" = xyes -then : - printf "%s\n" "#define HAVE_IFADDRS_H 1" >>confdefs.h - fi ac_fn_c_check_header_compile "$LINENO" "inttypes.h" "ac_cv_header_inttypes_h" "$ac_includes_default" if test "x$ac_cv_header_inttypes_h" = xyes @@ -11016,30 +11195,12 @@ if test "x$ac_cv_header_netdb_h" = xyes then : printf "%s\n" "#define HAVE_NETDB_H 1" >>confdefs.h -fi -ac_fn_c_check_header_compile "$LINENO" "netgroup.h" "ac_cv_header_netgroup_h" "$ac_includes_default" -if test "x$ac_cv_header_netgroup_h" = xyes -then : - printf "%s\n" "#define HAVE_NETGROUP_H 1" >>confdefs.h - fi ac_fn_c_check_header_compile "$LINENO" "pam/pam_appl.h" "ac_cv_header_pam_pam_appl_h" "$ac_includes_default" if test "x$ac_cv_header_pam_pam_appl_h" = xyes then : printf "%s\n" "#define HAVE_PAM_PAM_APPL_H 1" >>confdefs.h -fi -ac_fn_c_check_header_compile "$LINENO" "paths.h" "ac_cv_header_paths_h" "$ac_includes_default" -if test "x$ac_cv_header_paths_h" = xyes -then : - printf "%s\n" "#define HAVE_PATHS_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "poll.h" "ac_cv_header_poll_h" "$ac_includes_default" -if test "x$ac_cv_header_poll_h" = xyes -then : - printf "%s\n" "#define HAVE_POLL_H 1" >>confdefs.h - fi ac_fn_c_check_header_compile "$LINENO" "pty.h" "ac_cv_header_pty_h" "$ac_includes_default" if test "x$ac_cv_header_pty_h" = xyes @@ -11082,12 +11243,6 @@ if test "x$ac_cv_header_stddef_h" = xyes then : printf "%s\n" "#define HAVE_STDDEF_H 1" >>confdefs.h -fi -ac_fn_c_check_header_compile "$LINENO" "stdint.h" "ac_cv_header_stdint_h" "$ac_includes_default" -if test "x$ac_cv_header_stdint_h" = xyes -then : - printf "%s\n" "#define HAVE_STDINT_H 1" >>confdefs.h - fi ac_fn_c_check_header_compile "$LINENO" "string.h" "ac_cv_header_string_h" "$ac_includes_default" if test "x$ac_cv_header_string_h" = xyes @@ -11232,12 +11387,6 @@ if test "x$ac_cv_header_sys_sysmacros_h" = xyes then : printf "%s\n" "#define HAVE_SYS_SYSMACROS_H 1" >>confdefs.h -fi -ac_fn_c_check_header_compile "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_time_h" = xyes -then : - printf "%s\n" "#define HAVE_SYS_TIME_H 1" >>confdefs.h - fi ac_fn_c_check_header_compile "$LINENO" "sys/timers.h" "ac_cv_header_sys_timers_h" "$ac_includes_default" if test "x$ac_cv_header_sys_timers_h" = xyes @@ -11250,12 +11399,6 @@ if test "x$ac_cv_header_sys_vfs_h" = xyes then : printf "%s\n" "#define HAVE_SYS_VFS_H 1" >>confdefs.h -fi -ac_fn_c_check_header_compile "$LINENO" "time.h" "ac_cv_header_time_h" "$ac_includes_default" -if test "x$ac_cv_header_time_h" = xyes -then : - printf "%s\n" "#define HAVE_TIME_H 1" >>confdefs.h - fi ac_fn_c_check_header_compile "$LINENO" "tmpdir.h" "ac_cv_header_tmpdir_h" "$ac_includes_default" if test "x$ac_cv_header_tmpdir_h" = xyes @@ -11286,12 +11429,6 @@ if test "x$ac_cv_header_usersec_h" = xyes then : printf "%s\n" "#define HAVE_USERSEC_H 1" >>confdefs.h -fi -ac_fn_c_check_header_compile "$LINENO" "util.h" "ac_cv_header_util_h" "$ac_includes_default" -if test "x$ac_cv_header_util_h" = xyes -then : - printf "%s\n" "#define HAVE_UTIL_H 1" >>confdefs.h - fi ac_fn_c_check_header_compile "$LINENO" "utime.h" "ac_cv_header_utime_h" "$ac_includes_default" if test "x$ac_cv_header_utime_h" = xyes @@ -11325,6 +11462,116 @@ then : fi +# Create replacement header files for common headers that are missing on this +# platform. Usually these are just empty, but in some cases they'll include +# the equivalent file. This avoids having to wrap those includes in +# '#ifdef HAVE_FOO_H'. If we create any such headers, add the path to includes. +COMPATINCLUDESDIR="openbsd-compat/include" +COMPATINCLUDES="" + for ac_header in endian.h ifaddrs.h libgen.h paths.h netgroup.h nlist.h poll.h stdint.h sys/mman.h sys/stat.h sys/statvfs.h sys/time.h sys/un.h time.h util.h +do : + as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes" +then : + cat >>confdefs.h <<_ACEOF +#define `printf "%s\n" "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + + # Remove any old shims. + rm -f "$COMPATINCLUDESDIR/$ac_header" + +else $as_nop + + COMPATINCLUDES="$COMPATINCLUDESDIR" + header="$COMPATINCLUDES/$ac_header" + dir=`dirname "$header"` + mkdir -p "$dir" + case "$ac_header" in + poll.h) echo '#ifdef HAVE_SYS_POLL_H' + echo '#include ' + echo '#endif' ;; + *) ;; + esac >"$header" + +fi + +done + +for include in sys/queue.h sys/tree.h; do + COMPATINCLUDES="$COMPATINCLUDESDIR" + header="$COMPATINCLUDES/$include" + dir=`dirname "$header"` + mkdir -p "$dir" + case "$include" in + sys/queue.h) + echo '#include "openbsd-compat/sys-queue.h"' + ;; + sys/tree.h) + echo '#include "openbsd-compat/sys-tree.h"' + ;; + esac >"$header" +done + +ac_fn_check_decl "$LINENO" "le32toh" "ac_cv_have_decl_le32toh" " +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_ENDIAN_H +# include +#endif + +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_le32toh" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_LE32TOH $ac_have_decl" >>confdefs.h +ac_fn_check_decl "$LINENO" "le64toh" "ac_cv_have_decl_le64toh" " +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_ENDIAN_H +# include +#endif + +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_le64toh" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_LE64TOH $ac_have_decl" >>confdefs.h +ac_fn_check_decl "$LINENO" "htole64" "ac_cv_have_decl_htole64" " +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_ENDIAN_H +# include +#endif + +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_htole64" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_HTOLE64 $ac_have_decl" >>confdefs.h + + # On some platforms (eg SunOS4) sys/audit.h requires sys/[time|types|label.h] # to be included first. ac_fn_c_check_header_compile "$LINENO" "sys/audit.h" "ac_cv_header_sys_audit_h" " @@ -11506,6 +11753,12 @@ SPP_MSG="no" # the --with-solaris-privs option and --with-sandbox=solaris). SOLARIS_PRIVS="no" +# Default shared library extension +SHLIBEXT=".so" + +# See OpenBSD section in $host case below. +need_pledge_inet="" + # Check for some target-specific stuff case "$host" in *-*-aix*) @@ -11519,6 +11772,7 @@ printf %s "checking if compiler allows macro redefinitions... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ +#include #define testmacro foo #define testmacro bar int @@ -11768,9 +12022,6 @@ printf "%s\n" "#define LOGIN_NEEDS_UTMPX 1" >>confdefs.h printf "%s\n" "#define SPT_TYPE SPT_REUSEARGV" >>confdefs.h -printf "%s\n" "#define SSHPAM_CHAUTHTOK_NEEDS_RUID 1" >>confdefs.h - - printf "%s\n" "#define PTY_ZEROREAD 1" >>confdefs.h @@ -11820,8 +12071,14 @@ printf "%s\n" "#define FILESYSTEM_NO_BACKSLASH 1" >>confdefs.h # Cygwin defines optargs, optargs as declspec(dllimport) for historical # reasons which cause compile warnings, so we disable those warnings. { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wno-attributes" >&5 + ossh_cache_var=ossh_cv_cflag__Wno_attributes + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wno-attributes" >&5 printf %s "checking if $CC supports compile flag -Wno-attributes... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wno-attributes" _define_flag="" @@ -11886,14 +12143,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -11953,12 +12208,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -11967,13 +12220,18 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } + SHLIBEXT=".dll" ;; *-*-dgux*) @@ -12029,9 +12287,7 @@ fi printf "%s\n" "#define BROKEN_SETREGID 1" >>confdefs.h - -printf "%s\n" "#define BROKEN_GLOB 1" >>confdefs.h - + broken_glob=yes # OS X glob does not do what we expect printf "%s\n" "#define BIND_8_COMPAT 1" >>confdefs.h @@ -12138,6 +12394,7 @@ fi printf "%s\n" "#define BROKEN_POLL 1" >>confdefs.h + SHLIBEXT=".dylib" ;; *-*-dragonfly*) SSHDLIBS="$SSHDLIBS" @@ -12390,6 +12647,46 @@ printf "%s\n" "#define _PATH_BTMP \"/var/log/btmp\"" >>confdefs.h printf "%s\n" "#define LINUX_OOM_ADJUST 1" >>confdefs.h +# Check whether --with-linux-memlock-onfault was given. +if test ${with_linux_memlock_onfault+y} +then : + withval=$with_linux_memlock_onfault; + if test "x$withval" != "xno" ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for MCL_ONFAULT" >&5 +printf %s "checking for MCL_ONFAULT... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + #include +int +main (void) +{ + mlockall(MCL_FUTURE | MCL_ONFAULT); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: supported" >&5 +printf "%s\n" "supported" >&6; } + +printf "%s\n" "#define LINUX_MEMLOCK_ONFAULT 1" >>confdefs.h + +else $as_nop + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not supported" >&5 +printf "%s\n" "not supported" >&6; } + as_fn_error $? "MCL_ONFAULT is not available on your system" "$LINENO" 5 + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + fi + +fi + + + printf "%s\n" "#define SYSTEMD_NOTIFY 1" >>confdefs.h inet6_default_4in6=yes @@ -12645,6 +12942,9 @@ printf "%s\n" "#define LOCKED_PASSWD_PREFIX \"*LOCKED*\"" >>confdefs.h printf "%s\n" "#define SSH_TUN_FREEBSD 1" >>confdefs.h + +printf "%s\n" "#define SSH_TUN_COMPAT_AF 1" >>confdefs.h + ac_fn_c_check_header_compile "$LINENO" "net/if_tap.h" "ac_cv_header_net_if_tap_h" "$ac_includes_default" if test "x$ac_cv_header_net_if_tap_h" = xyes then : @@ -12655,9 +12955,7 @@ printf "%s\n" "#define SSH_TUN_NO_L2 1" >>confdefs.h fi - -printf "%s\n" "#define BROKEN_GLOB 1" >>confdefs.h - + broken_glob=yes # FreeBSD glob does not do what we need TEST_MALLOC_OPTIONS="AJRX" # Preauth crypto occasionally uses file descriptors for crypto offload # and will crash if they cannot be opened. @@ -12707,6 +13005,53 @@ printf "%s\n" "#define SSH_TUN_OPENBSD 1" >>confdefs.h printf "%s\n" "#define SYSLOG_R_SAFE_IN_SIGHAND 1" >>confdefs.h TEST_MALLOC_OPTIONS="SJRU" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pledge(2) allows IP_TOS" >&5 +printf %s "checking whether pledge(2) allows IP_TOS... " >&6; } + if test "$cross_compiling" = yes +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: cannot test" >&5 +printf "%s\n" "$as_me: WARNING: cross compiling: cannot test" >&2;} +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +#include +#include + +int +main (void) +{ + +int s, one = 1; +if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) + err(1, "socket"); +if (pledge("stdio", NULL) == -1) + err(1, "pledge"); +if (setsockopt(s, IPPROTO_IP, IP_TOS, &one, sizeof(one)) == -1) + err(1, "setsockopt"); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + need_pledge_inet=1 + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + ;; *-*-solaris*) if test "x$withval" != "xno" ; then @@ -12718,9 +13063,6 @@ printf "%s\n" "#define SYSLOG_R_SAFE_IN_SIGHAND 1" >>confdefs.h printf "%s\n" "#define PAM_TTY_KLUDGE 1" >>confdefs.h - -printf "%s\n" "#define SSHPAM_CHAUTHTOK_NEEDS_RUID 1" >>confdefs.h - printf "%s\n" "#define LOCKED_PASSWD_STRING \"*LK*\"" >>confdefs.h # Pushing STREAMS modules will cause sshd to acquire a controlling tty. @@ -13357,6 +13699,15 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ fi +if test -z "$need_pledge_inet" ; then + printf "%s\n" "#define PLEDGE_EXTRA_INET /**/" >>confdefs.h + +else + +printf "%s\n" "#define PLEDGE_EXTRA_INET \"inet \"" >>confdefs.h + +fi + # Checks for libraries. ac_fn_c_check_func "$LINENO" "setsockopt" "ac_cv_func_setsockopt" if test "x$ac_cv_func_setsockopt" = xyes @@ -13640,6 +13991,55 @@ printf "%s\n" "#define HAVE_BASENAME 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "sqrt" "ac_cv_func_sqrt" +if test "x$ac_cv_func_sqrt" = xyes +then : + +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqrt in -lm" >&5 +printf %s "checking for sqrt in -lm... " >&6; } +if test ${ac_cv_lib_m_sqrt+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lm $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char sqrt (); +int +main (void) +{ +return sqrt (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_m_sqrt=yes +else $as_nop + ac_cv_lib_m_sqrt=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sqrt" >&5 +printf "%s\n" "$ac_cv_lib_m_sqrt" >&6; } +if test "x$ac_cv_lib_m_sqrt" = xyes +then : + TESTLIBS="$TESTLIBS -lm" +fi + +fi + + + zlib=yes # Check whether --with-zlib was given. @@ -14849,6 +15249,33 @@ printf "%s\n" "#define calloc rpl_calloc" >>confdefs.h fi + + for ac_func in glob +do : + ac_fn_c_check_func "$LINENO" "glob" "ac_cv_func_glob" +if test "x$ac_cv_func_glob" = xyes +then : + printf "%s\n" "#define HAVE_GLOB 1" >>confdefs.h + for ac_header in glob.h +do : + ac_fn_c_check_header_compile "$LINENO" "glob.h" "ac_cv_header_glob_h" "$ac_includes_default" +if test "x$ac_cv_header_glob_h" = xyes +then : + printf "%s\n" "#define HAVE_GLOB_H 1" >>confdefs.h + use_system_glob=yes +else $as_nop + use_system_glob=no +fi + +done + +else $as_nop + use_system_glob=no + +fi + +done + # Check for ALTDIRFUNC glob() extension { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GLOB_ALTDIRFUNC support" >&5 printf %s "checking for GLOB_ALTDIRFUNC support... " >&6; } @@ -14876,6 +15303,7 @@ else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } + use_system_glob=no fi @@ -14909,6 +15337,8 @@ else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } + use_system_glob=no + fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext @@ -14946,6 +15376,7 @@ else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } + use_system_glob=no fi @@ -14960,7 +15391,35 @@ else $as_nop ac_have_decl=0 fi printf "%s\n" "#define HAVE_DECL_GLOB_NOMATCH $ac_have_decl" >>confdefs.h +if test $ac_have_decl = 1 +then : + +else $as_nop + use_system_glob=no +fi + + +if test "x$broken_glob" = "xyes"; then + +printf "%s\n" "#define BROKEN_GLOB 1" >>confdefs.h + + use_system_glob=no +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can use the system glob" >&5 +printf %s "checking if we can use the system glob... " >&6; } +if test "x$use_system_glob" = "xyes" ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + # Remove any old shims. + rm -f "$COMPATINCLUDESDIR/glob.h" +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + COMPATINCLUDES="$COMPATINCLUDESDIR" + mkdir -p "$COMPATINCLUDES" + echo '#include "openbsd-compat/glob.h"' >$COMPATINCLUDES/glob.h +fi ac_fn_check_decl "$LINENO" "VIS_ALL" "ac_cv_have_decl_VIS_ALL" "#include " "$ac_c_undeclared_builtin_options" "CFLAGS" @@ -15021,6 +15480,21 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ fi +ac_fn_c_check_member "$LINENO" "struct dirent" "d_type" "ac_cv_member_struct_dirent_d_type" " +#ifdef HAVE_DIRENT_H +#include +#endif + +" +if test "x$ac_cv_member_struct_dirent_d_type" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_DIRENT_D_TYPE 1" >>confdefs.h + + +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for /proc/pid/fd directory" >&5 printf %s "checking for /proc/pid/fd directory... " >&6; } if test -d "/proc/$$/fd" ; then @@ -15324,6 +15798,95 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi +# Check whether user wants wtmpdb support +WTMPDB_MSG="no" + +# Check whether --with-wtmpdb was given. +if test ${with_wtmpdb+y} +then : + withval=$with_wtmpdb; if test "x$withval" != "xno" ; then + if test "x$withval" = "xyes" ; then + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $PKGCONFIG knows about wtmpdb" >&5 +printf %s "checking if $PKGCONFIG knows about wtmpdb... " >&6; } + if "$PKGCONFIG" libwtmpdb; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + use_pkgconfig_for_libwtmpdb=yes + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + fi + fi + else + CPPFLAGS="$CPPFLAGS -I${withval}/include" + if test -n "${rpath_opt}"; then + LDFLAGS="-L${withval}/lib ${rpath_opt}${withval}/lib ${LDFLAGS}" + else + LDFLAGS="-L${withval}/lib ${LDFLAGS}" + fi + fi + if test "x$use_pkgconfig_for_libwtmpdb" = "xyes"; then + LIBWTMPDB=`$PKGCONFIG --libs libwtmpdb` + CPPFLAGS="$CPPFLAGS `$PKGCONFIG --cflags libwtmpdb`" + else + LIBWTMPDB="-lwtmpdb" + fi + OTHERLIBS=`echo $LIBWTMPDB | sed 's/-lwtmpdb//'` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for wtmpdb_login in -lwtmpdb" >&5 +printf %s "checking for wtmpdb_login in -lwtmpdb... " >&6; } +if test ${ac_cv_lib_wtmpdb_wtmpdb_login+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lwtmpdb $OTHERLIBS + $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char wtmpdb_login (); +int +main (void) +{ +return wtmpdb_login (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_wtmpdb_wtmpdb_login=yes +else $as_nop + ac_cv_lib_wtmpdb_wtmpdb_login=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_wtmpdb_wtmpdb_login" >&5 +printf "%s\n" "$ac_cv_lib_wtmpdb_wtmpdb_login" >&6; } +if test "x$ac_cv_lib_wtmpdb_wtmpdb_login" = xyes +then : + +printf "%s\n" "#define USE_WTMPDB 1" >>confdefs.h + + WTMPDB_MSG="yes" + + +else $as_nop + as_fn_error $? "libwtmpdb not found" "$LINENO" 5 +fi + + fi + +fi + + + AUDIT_MODULE=none # Check whether --with-audit was given. @@ -15523,8 +16086,14 @@ if test "x$use_pie" != "xno"; then SAVED_CFLAGS="$CFLAGS" SAVED_LDFLAGS="$LDFLAGS" { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -fPIE" >&5 + ossh_cache_var=ossh_cv_cflag__fPIE + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -fPIE" >&5 printf %s "checking if $CC supports compile flag -fPIE... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -fPIE" _define_flag="" @@ -15589,14 +16158,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -15656,12 +16223,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -15670,16 +16235,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -pie" >&5 + ossh_cache_var=ossh_cv_ldflag__pie + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -pie" >&5 printf %s "checking if $LD supports link flag -pie... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $WERROR -pie" _define_flag="" @@ -15744,14 +16319,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" LDFLAGS="$saved_LDFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" LDFLAGS="$saved_LDFLAGS $_define_flag" else $as_nop @@ -15812,12 +16385,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" LDFLAGS="$saved_LDFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" LDFLAGS="$saved_LDFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -15826,13 +16397,17 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" LDFLAGS="$saved_LDFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } # We use both -fPIE and -pie or neither. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether both -fPIE and -pie are supported" >&5 @@ -16099,6 +16674,12 @@ if test "x$ac_cv_func_freezero" = xyes then : printf "%s\n" "#define HAVE_FREEZERO 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "fstatat" "ac_cv_func_fstatat" +if test "x$ac_cv_func_fstatat" = xyes +then : + printf "%s\n" "#define HAVE_FSTATAT 1" >>confdefs.h + fi ac_fn_c_check_func "$LINENO" "fstatfs" "ac_cv_func_fstatfs" if test "x$ac_cv_func_fstatfs" = xyes @@ -16159,12 +16740,6 @@ if test "x$ac_cv_func_getopt" = xyes then : printf "%s\n" "#define HAVE_GETOPT 1" >>confdefs.h -fi -ac_fn_c_check_func "$LINENO" "getpagesize" "ac_cv_func_getpagesize" -if test "x$ac_cv_func_getpagesize" = xyes -then : - printf "%s\n" "#define HAVE_GETPAGESIZE 1" >>confdefs.h - fi ac_fn_c_check_func "$LINENO" "getpeereid" "ac_cv_func_getpeereid" if test "x$ac_cv_func_getpeereid" = xyes @@ -16213,12 +16788,6 @@ if test "x$ac_cv_func_getttyent" = xyes then : printf "%s\n" "#define HAVE_GETTTYENT 1" >>confdefs.h -fi -ac_fn_c_check_func "$LINENO" "glob" "ac_cv_func_glob" -if test "x$ac_cv_func_glob" = xyes -then : - printf "%s\n" "#define HAVE_GLOB 1" >>confdefs.h - fi ac_fn_c_check_func "$LINENO" "group_from_gid" "ac_cv_func_group_from_gid" if test "x$ac_cv_func_group_from_gid" = xyes @@ -16303,12 +16872,24 @@ if test "x$ac_cv_func_mkdtemp" = xyes then : printf "%s\n" "#define HAVE_MKDTEMP 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "mmap" "ac_cv_func_mmap" +if test "x$ac_cv_func_mmap" = xyes +then : + printf "%s\n" "#define HAVE_MMAP 1" >>confdefs.h + fi ac_fn_c_check_func "$LINENO" "ngetaddrinfo" "ac_cv_func_ngetaddrinfo" if test "x$ac_cv_func_ngetaddrinfo" = xyes then : printf "%s\n" "#define HAVE_NGETADDRINFO 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "nlist" "ac_cv_func_nlist" +if test "x$ac_cv_func_nlist" = xyes +then : + printf "%s\n" "#define HAVE_NLIST 1" >>confdefs.h + fi ac_fn_c_check_func "$LINENO" "nsleep" "ac_cv_func_nsleep" if test "x$ac_cv_func_nsleep" = xyes @@ -16669,12 +17250,24 @@ if test "x$ac_cv_func_truncate" = xyes then : printf "%s\n" "#define HAVE_TRUNCATE 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "unlinkat" "ac_cv_func_unlinkat" +if test "x$ac_cv_func_unlinkat" = xyes +then : + printf "%s\n" "#define HAVE_UNLINKAT 1" >>confdefs.h + fi ac_fn_c_check_func "$LINENO" "unsetenv" "ac_cv_func_unsetenv" if test "x$ac_cv_func_unsetenv" = xyes then : printf "%s\n" "#define HAVE_UNSETENV 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "unveil" "ac_cv_func_unveil" +if test "x$ac_cv_func_unveil" = xyes +then : + printf "%s\n" "#define HAVE_UNVEIL 1" >>confdefs.h + fi ac_fn_c_check_func "$LINENO" "updwtmpx" "ac_cv_func_updwtmpx" if test "x$ac_cv_func_updwtmpx" = xyes @@ -16726,6 +17319,40 @@ then : fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports __builtin_popcount" >&5 +printf %s "checking whether compiler supports __builtin_popcount... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + +int +main (void) +{ + int x = 123, y; + y = __builtin_popcount(123); + exit(y == 6 ? 0 : -1); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +printf "%s\n" "#define MISSING_BUILTIN_POPCOUNT 1" >>confdefs.h + + + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ac_fn_check_decl "$LINENO" "bzero" "ac_cv_have_decl_bzero" "$ac_includes_default" "$ac_c_undeclared_builtin_options" "CFLAGS" if test "x$ac_cv_have_decl_bzero" = xyes then : @@ -16868,15 +17495,12 @@ then : fi -enable_dsa= -# Check whether --enable-dsa-keys was given. -if test ${enable_dsa_keys+y} -then : - enableval=$enable_dsa_keys; - if test "x$enableval" != "xno" ; then - enable_dsa=1 - fi +enable_sk_standalone= +# Check whether --with-security-key-standalone was given. +if test ${with_security_key_standalone+y} +then : + withval=$with_security_key_standalone; enable_sk_standalone=$withval fi @@ -17315,6 +17939,32 @@ fi printf "%s\n" "#define HAVE_DECL_OFFSETOF $ac_have_decl" >>confdefs.h +ac_fn_check_decl "$LINENO" "INFINITY" "ac_cv_have_decl_INFINITY" "#include + +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_INFINITY" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_INFINITY $ac_have_decl" >>confdefs.h +if test $ac_have_decl = 1 +then : + +else $as_nop + ac_fn_check_decl "$LINENO" "__builtin_inff" "ac_cv_have_decl___builtin_inff" "$ac_includes_default" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl___builtin_inff" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL___BUILTIN_INFF $ac_have_decl" >>confdefs.h + +fi + + # extra bits for select(2) ac_fn_check_decl "$LINENO" "howmany" "ac_cv_have_decl_howmany" " #include @@ -17938,6 +18588,9 @@ printf %s "checking whether snprintf can declare const char *fmt... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ +#ifdef _FORTIFY_SOURCE +#undef _FORTIFY_SOURCE +#endif #include int snprintf(char *a, size_t b, const char *c, ...) { return 0; } @@ -18620,7 +19273,37 @@ if ac_fn_c_try_link "$LINENO" then : else $as_nop - as_fn_error $? "*** working libcrypto not found, check config.log" "$LINENO" 5 + + # As of early 2026, BoringSSL libcrypto needs -lstdc++ for + # destructors so try that before giving up. + LIBS="$LIBS -lstdc++" + CHANNELLIBS="$CHANNELLIBS -lstdc++" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char RAND_add (); +int +main (void) +{ +return RAND_add (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + +else $as_nop + + as_fn_error $? "*** working libcrypto not found, check config.log" "$LINENO" 5 + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext @@ -18783,8 +19466,8 @@ then : *) ;; # Assume all other versions are good. esac ;; - 30*) - # OpenSSL 3; we use the 1.1x API + 30*|40*) + # OpenSSL 3 & 4; we use the 1.1x API # https://openssl.org/policies/general/versioning-policy.html CPPFLAGS="$CPPFLAGS -DOPENSSL_API_COMPAT=0x10100000L" ;; @@ -18947,12 +19630,6 @@ if test "x$ac_cv_func_DES_crypt" = xyes then : printf "%s\n" "#define HAVE_DES_CRYPT 1" >>confdefs.h -fi -ac_fn_c_check_func "$LINENO" "DSA_generate_parameters_ex" "ac_cv_func_DSA_generate_parameters_ex" -if test "x$ac_cv_func_DSA_generate_parameters_ex" = xyes -then : - printf "%s\n" "#define HAVE_DSA_GENERATE_PARAMETERS_EX 1" >>confdefs.h - fi ac_fn_c_check_func "$LINENO" "EVP_DigestSign" "ac_cv_func_EVP_DigestSign" if test "x$ac_cv_func_EVP_DigestSign" = xyes @@ -19016,29 +19693,32 @@ then : fi - # OpenSSL_add_all_algorithms may be a macro. - ac_fn_c_check_func "$LINENO" "OpenSSL_add_all_algorithms" "ac_cv_func_OpenSSL_add_all_algorithms" -if test "x$ac_cv_func_OpenSSL_add_all_algorithms" = xyes + # LibreSSL/OpenSSL API differences + ac_fn_c_check_func "$LINENO" "EC_POINT_get_affine_coordinates" "ac_cv_func_EC_POINT_get_affine_coordinates" +if test "x$ac_cv_func_EC_POINT_get_affine_coordinates" = xyes then : + printf "%s\n" "#define HAVE_EC_POINT_GET_AFFINE_COORDINATES 1" >>confdefs.h -printf "%s\n" "#define HAVE_OPENSSL_ADD_ALL_ALGORITHMS 1" >>confdefs.h - -else $as_nop - ac_fn_check_decl "$LINENO" "OpenSSL_add_all_algorithms" "ac_cv_have_decl_OpenSSL_add_all_algorithms" "#include - -" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_OpenSSL_add_all_algorithms" = xyes +fi +ac_fn_c_check_func "$LINENO" "EC_POINT_get_affine_coordinates_GFp" "ac_cv_func_EC_POINT_get_affine_coordinates_GFp" +if test "x$ac_cv_func_EC_POINT_get_affine_coordinates_GFp" = xyes then : - -printf "%s\n" "#define HAVE_OPENSSL_ADD_ALL_ALGORITHMS 1" >>confdefs.h + printf "%s\n" "#define HAVE_EC_POINT_GET_AFFINE_COORDINATES_GFP 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "EC_POINT_set_affine_coordinates" "ac_cv_func_EC_POINT_set_affine_coordinates" +if test "x$ac_cv_func_EC_POINT_set_affine_coordinates" = xyes +then : + printf "%s\n" "#define HAVE_EC_POINT_SET_AFFINE_COORDINATES 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "EC_POINT_set_affine_coordinates_GFp" "ac_cv_func_EC_POINT_set_affine_coordinates_GFp" +if test "x$ac_cv_func_EC_POINT_set_affine_coordinates_GFp" = xyes +then : + printf "%s\n" "#define HAVE_EC_POINT_SET_AFFINE_COORDINATES_GFP 1" >>confdefs.h - - # LibreSSL/OpenSSL API differences - ac_fn_c_check_func "$LINENO" "EVP_CIPHER_CTX_iv" "ac_cv_func_EVP_CIPHER_CTX_iv" +fi +ac_fn_c_check_func "$LINENO" "EVP_CIPHER_CTX_iv" "ac_cv_func_EVP_CIPHER_CTX_iv" if test "x$ac_cv_func_EVP_CIPHER_CTX_iv" = xyes then : printf "%s\n" "#define HAVE_EVP_CIPHER_CTX_IV 1" >>confdefs.h @@ -19431,6 +20111,10 @@ printf %s "checking whether OpenSSL has ED25519 support... " >&6; } #include #include + #include + #ifdef OPENSSL_NO_EC + # error "OpenSSL has no EC support." + #endif int main (void) @@ -19463,63 +20147,18 @@ printf "%s\n" "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - - openssl_dsa=no - if test ! -z "$enable_dsa" ; then - ac_fn_check_decl "$LINENO" "OPENSSL_NO_DSA" "ac_cv_have_decl_OPENSSL_NO_DSA" " #include - -" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_OPENSSL_NO_DSA" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 fi -printf "%s\n" "#define HAVE_DECL_OPENSSL_NO_DSA $ac_have_decl" >>confdefs.h -if test $ac_have_decl = 1 -then : -else $as_nop +# PKCS11/U2F depend on OpenSSL and dlopen(). +enable_pkcs11=yes +enable_sk=yes - ac_fn_check_decl "$LINENO" "OPENSSL_IS_BORINGSSL" "ac_cv_have_decl_OPENSSL_IS_BORINGSSL" " #include +ac_fn_check_decl "$LINENO" "OPENSSL_IS_AWSLC" "ac_cv_have_decl_OPENSSL_IS_AWSLC" "#include " "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_OPENSSL_IS_BORINGSSL" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 -fi -printf "%s\n" "#define HAVE_DECL_OPENSSL_IS_BORINGSSL $ac_have_decl" >>confdefs.h -if test $ac_have_decl = 1 +if test "x$ac_cv_have_decl_OPENSSL_IS_AWSLC" = xyes then : - -else $as_nop - openssl_dsa=yes -fi - - -fi - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable DSA key support" >&5 -printf %s "checking whether to enable DSA key support... " >&6; } - if test "x$openssl_dsa" = "xno"; then - as_fn_error $? "DSA requested but not supported by OpenSSL" "$LINENO" 5 - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - -printf "%s\n" "#define WITH_DSA 1" >>confdefs.h - - fi - fi -fi - -# PKCS11/U2F depend on OpenSSL and dlopen(). -enable_pkcs11=yes -enable_sk=yes -if test "x$openssl" != "xyes" ; then - enable_pkcs11="disabled; missing libcrypto" + enable_pkcs11="disabled; PKCS#11 not supported with AWS-LC" fi if test "x$ac_cv_func_dlopen" != "xyes" ; then enable_pkcs11="disabled; missing dlopen(3)" @@ -19718,6 +20357,21 @@ fi fi fi +# Check for standalone SecurityKeyProvider +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build standalone sk-libfido2" >&5 +printf %s "checking whether to build standalone sk-libfido2... " >&6; } +if test "x$enable_sk_standalone" = "xyes" ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + SK_STANDALONE=sk-libfido2$SHLIBEXT + +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + SK_STANDALONE="" + +fi + ac_fn_c_check_func "$LINENO" "arc4random" "ac_cv_func_arc4random" if test "x$ac_cv_func_arc4random" = xyes then : @@ -20339,6 +20993,44 @@ printf "%s\n" "#define HAVE_NFDS_T 1" >>confdefs.h fi +if test "x$ac_cv_type_nfds_t" != "xyes"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if poll nfds_t is unsigned long" >&5 +printf %s "checking if poll nfds_t is unsigned long... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#ifdef HAVE_POLL_H +#include +#endif +#ifdef HAVE_SYS_POLL_H +#include +#endif + int poll(struct pollfd *, unsigned long, int timeout); + +int +main (void) +{ +return poll(0, 0, 0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +printf "%s\n" "#define POLL_NFDS_T_ULONG 1" >>confdefs.h + +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + # Decide which sandbox style to use sandbox_arg="" @@ -20536,23 +21228,7 @@ fi fi -if test "x$sandbox_arg" = "xpledge" || \ - ( test -z "$sandbox_arg" && test "x$ac_cv_func_pledge" = "xyes" ) ; then - test "x$ac_cv_func_pledge" != "xyes" && \ - as_fn_error $? "pledge sandbox requires pledge(2) support" "$LINENO" 5 - SANDBOX_STYLE="pledge" - -printf "%s\n" "#define SANDBOX_PLEDGE 1" >>confdefs.h - -elif test "x$sandbox_arg" = "xsystrace" || \ - ( test -z "$sandbox_arg" && test "x$have_systr_policy_kill" = "x1" ) ; then - test "x$have_systr_policy_kill" != "x1" && \ - as_fn_error $? "systrace sandbox requires systrace headers and SYSTR_POLICY_KILL support" "$LINENO" 5 - SANDBOX_STYLE="systrace" - -printf "%s\n" "#define SANDBOX_SYSTRACE 1" >>confdefs.h - -elif test "x$sandbox_arg" = "xdarwin" || \ +if test "x$sandbox_arg" = "xdarwin" || \ ( test -z "$sandbox_arg" && test "x$ac_cv_func_sandbox_init" = "xyes" && \ test "x$ac_cv_header_sandbox_h" = "xyes") ; then test "x$ac_cv_func_sandbox_init" != "xyes" -o \ @@ -22226,7 +22902,11 @@ int main(void) long long num = 0x7fffffffffffffffll; #endif strcpy(expected_out, "9223372036854775807"); +#if (SIZEOF_LONG_INT == 8) + snprintf(buf, mazsize, "%ld", num); +#else snprintf(buf, mazsize, "%lld", num); +#endif if(strcmp(buf, expected_out) != 0) exit(1); exit(0); @@ -26307,13 +26987,59 @@ printf "%s\n" "no" >&6; } fi +# Extract the first word of "tmux", so it can be a program name with args. +set dummy tmux; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_TMUX+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $TMUX in + [\\/]* | ?:[\\/]*) + ac_cv_path_TMUX="$TMUX" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_TMUX="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +TMUX=$ac_cv_path_TMUX +if test -n "$TMUX"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $TMUX" >&5 +printf "%s\n" "$TMUX" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + CFLAGS="${CFLAGS} ${CFLAGS_AFTER}" LDFLAGS="${LDFLAGS} ${LDFLAGS_AFTER}" # Make a copy of CFLAGS/LDFLAGS without PIE options. -LDFLAGS_NOPIE=`echo "$LDFLAGS" | sed 's/ -pie//'` -CFLAGS_NOPIE=`echo "$CFLAGS" | sed 's/ -fPIE//'` +LDFLAGS_NOPIE=`echo "$LDFLAGS" | sed 's/^-pie //;s/ -pie//g'` +CFLAGS_NOPIE=`echo "$CFLAGS" | sed 's/^-fPIE //;s/ -fPIE//g'` + diff --git a/configure.ac b/configure.ac index 9053a9a..a8e9df6 100644 --- a/configure.ac +++ b/configure.ac @@ -114,11 +114,6 @@ AC_C_INLINE AC_CHECK_DECL([LLONG_MAX], [have_llong_max=1], , [#include ]) AC_CHECK_DECL([LONG_LONG_MAX], [have_long_long_max=1], , [#include ]) -AC_CHECK_DECL([SYSTR_POLICY_KILL], [have_systr_policy_kill=1], , [ - #include - #include - #include -]) AC_CHECK_DECL([RLIMIT_NPROC], [AC_DEFINE([HAVE_RLIMIT_NPROC], [], [sys/resource.h has RLIMIT_NPROC])], , [ #include @@ -363,6 +358,19 @@ AC_COMPILE_IFELSE( [ AC_MSG_RESULT([no]) ] ) +saved_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Werror" +AC_MSG_CHECKING([if compiler supports __nonstring__ attribute on char arrays]) +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[#include ]], + [[ char __attribute__ ((__nonstring__)) h[5] = "hello"; return h[0]!='h'; ]])], + [ AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_ATTRIBUTE__NONSTRING__, [1], + [compiler supports nonstring attribute]) ], + [ AC_MSG_RESULT([no]) ] +) +CFLAGS="$saved_CFLAGS" + if test "x$no_attrib_nonnull" != "x1" ; then AC_DEFINE([HAVE_ATTRIBUTE__NONNULL__], [1], [Have attribute nonnull]) fi @@ -462,7 +470,6 @@ AC_CHECK_HEADERS([ \ crypt.h \ crypto/sha2.h \ dirent.h \ - endian.h \ elf.h \ err.h \ features.h \ @@ -470,10 +477,8 @@ AC_CHECK_HEADERS([ \ floatingpoint.h \ fnmatch.h \ getopt.h \ - glob.h \ ia.h \ iaf.h \ - ifaddrs.h \ inttypes.h \ langinfo.h \ limits.h \ @@ -483,10 +488,7 @@ AC_CHECK_HEADERS([ \ ndir.h \ net/if_tun.h \ netdb.h \ - netgroup.h \ pam/pam_appl.h \ - paths.h \ - poll.h \ pty.h \ readpassphrase.h \ rpc/types.h \ @@ -494,7 +496,6 @@ AC_CHECK_HEADERS([ \ sha2.h \ shadow.h \ stddef.h \ - stdint.h \ string.h \ strings.h \ sys/bitypes.h \ @@ -519,16 +520,13 @@ AC_CHECK_HEADERS([ \ sys/strtio.h \ sys/statvfs.h \ sys/sysmacros.h \ - sys/time.h \ sys/timers.h \ sys/vfs.h \ - time.h \ tmpdir.h \ ttyent.h \ ucred.h \ unistd.h \ usersec.h \ - util.h \ utime.h \ utmp.h \ utmpx.h \ @@ -536,6 +534,72 @@ AC_CHECK_HEADERS([ \ wchar.h \ ]) +# Create replacement header files for common headers that are missing on this +# platform. Usually these are just empty, but in some cases they'll include +# the equivalent file. This avoids having to wrap those includes in +# '#ifdef HAVE_FOO_H'. If we create any such headers, add the path to includes. +COMPATINCLUDESDIR="openbsd-compat/include" +COMPATINCLUDES="" +AC_CHECK_HEADERS([ \ + endian.h \ + ifaddrs.h \ + libgen.h \ + paths.h \ + netgroup.h \ + nlist.h \ + poll.h \ + stdint.h \ + sys/mman.h \ + sys/stat.h \ + sys/statvfs.h \ + sys/time.h \ + sys/un.h \ + time.h \ + util.h \ + ], [ + # Remove any old shims. + rm -f "$COMPATINCLUDESDIR/$ac_header" + ], [ + COMPATINCLUDES="$COMPATINCLUDESDIR" + header="$COMPATINCLUDES/$ac_header" + dir=`dirname "$header"` + mkdir -p "$dir" + case "$ac_header" in + poll.h) echo '#ifdef HAVE_SYS_POLL_H' + echo '#include ' + echo '#endif' ;; + *) ;; + esac >"$header" +]) + +dnl Now create replacement headers for those that we always want to shim. +for include in sys/queue.h sys/tree.h; do + COMPATINCLUDES="$COMPATINCLUDESDIR" + header="$COMPATINCLUDES/$include" + dir=`dirname "$header"` + mkdir -p "$dir" + case "$include" in + sys/queue.h) + echo '#include "openbsd-compat/sys-queue.h"' + ;; + sys/tree.h) + echo '#include "openbsd-compat/sys-tree.h"' + ;; + esac >"$header" +done + +AC_CHECK_DECLS([le32toh, le64toh, htole64], [], [], [ +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_ENDIAN_H +# include +#endif +]) + # On some platforms (eg SunOS4) sys/audit.h requires sys/[time|types|label.h] # to be included first. AC_CHECK_HEADERS([sys/audit.h], [], [], [ @@ -619,6 +683,12 @@ SPP_MSG="no" # the --with-solaris-privs option and --with-sandbox=solaris). SOLARIS_PRIVS="no" +# Default shared library extension +SHLIBEXT=".so" + +# See OpenBSD section in $host case below. +need_pledge_inet="" + # Check for some target-specific stuff case "$host" in *-*-aix*) @@ -630,6 +700,7 @@ case "$host" in AC_MSG_CHECKING([if compiler allows macro redefinitions]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[ +#include #define testmacro foo #define testmacro bar]], [[ exit(0); ]])], @@ -708,8 +779,6 @@ case "$host" in AC_DEFINE([SPT_TYPE], [SPT_REUSEARGV], [Define to a Set Process Title type if your system is supported by bsd-setproctitle.c]) - AC_DEFINE([SSHPAM_CHAUTHTOK_NEEDS_RUID], [1], - [AIX 5.2 and 5.3 (and presumably newer) require this]) AC_DEFINE([PTY_ZEROREAD], [1], [read(1) can return 0 for a non-closed fd]) AC_DEFINE([PLATFORM_SYS_DIR_UID], 2, [System dirs owned by bin (uid 2)]) AC_DEFINE([BROKEN_STRNDUP], 1, [strndup broken, see APAR IY61211]) @@ -737,6 +806,7 @@ case "$host" in # Cygwin defines optargs, optargs as declspec(dllimport) for historical # reasons which cause compile warnings, so we disable those warnings. OSSH_CHECK_CFLAG_COMPILE([-Wno-attributes]) + SHLIBEXT=".dll" ;; *-*-dgux*) AC_DEFINE([IP_TOS_IS_BROKEN], [1], @@ -766,7 +836,7 @@ int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) AC_DEFINE([SETEUID_BREAKS_SETUID]) AC_DEFINE([BROKEN_SETREUID]) AC_DEFINE([BROKEN_SETREGID]) - AC_DEFINE([BROKEN_GLOB], [1], [OS X glob does not do what we expect]) + broken_glob=yes # OS X glob does not do what we expect AC_DEFINE_UNQUOTED([BIND_8_COMPAT], [1], [Define if your resolver libs need this for getrrsetbyname]) AC_DEFINE([SSH_TUN_FREEBSD], [1], [Open tunnel devices the FreeBSD way]) @@ -796,6 +866,7 @@ int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) # cf. Apple bug 3710161 (not public, but searchable) AC_DEFINE([BROKEN_POLL], [1], [System poll(2) implementation is broken]) + SHLIBEXT=".dylib" ;; *-*-dragonfly*) SSHDLIBS="$SSHDLIBS" @@ -915,6 +986,27 @@ int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) AC_DEFINE([_PATH_BTMP], ["/var/log/btmp"], [log for bad login attempts]) AC_DEFINE([USE_BTMP]) AC_DEFINE([LINUX_OOM_ADJUST], [1], [Adjust Linux out-of-memory killer]) + AC_ARG_WITH([linux-memlock-onfault], + [ --with-linux-memlock-onfault Enables memory locking on Linux], + [ + if test "x$withval" != "xno" ; then + AC_MSG_CHECKING([for MCL_ONFAULT]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[ #include ]], + [[ mlockall(MCL_FUTURE | MCL_ONFAULT); ]], + )], + [ + AC_MSG_RESULT([supported]) + AC_DEFINE([LINUX_MEMLOCK_ONFAULT], [1], + [Lock all memory to protect sshd against Linux kcompactd] )], + [ + AC_MSG_RESULT([not supported]) + AC_MSG_ERROR([MCL_ONFAULT is not available on your system]) + ]) + fi + ], + ) + AC_DEFINE([SYSTEMD_NOTIFY], [1], [Have sshd notify systemd on start/reload]) inet6_default_4in6=yes case `uname -r` in @@ -1058,9 +1150,11 @@ mips-sony-bsd|mips-sony-newsos4) *-*-freebsd*) AC_DEFINE([LOCKED_PASSWD_PREFIX], ["*LOCKED*"], [Account locked with pw(1)]) AC_DEFINE([SSH_TUN_FREEBSD], [1], [Open tunnel devices the FreeBSD way]) + AC_DEFINE([SSH_TUN_COMPAT_AF], [1], + [Use tunnel device compatibility to OpenBSD]) AC_CHECK_HEADER([net/if_tap.h], , AC_DEFINE([SSH_TUN_NO_L2], [1], [No layer 2 tunnel support])) - AC_DEFINE([BROKEN_GLOB], [1], [FreeBSD glob does not do what we need]) + broken_glob=yes # FreeBSD glob does not do what we need TEST_MALLOC_OPTIONS="AJRX" # Preauth crypto occasionally uses file descriptors for crypto offload # and will crash if they cannot be opened. @@ -1094,6 +1188,28 @@ mips-sony-bsd|mips-sony-newsos4) AC_DEFINE([SYSLOG_R_SAFE_IN_SIGHAND], [1], [syslog_r function is safe to use in in a signal handler]) TEST_MALLOC_OPTIONS="SJRU" + AC_MSG_CHECKING([whether pledge(2) allows IP_TOS]) + AC_RUN_IFELSE( + [AC_LANG_PROGRAM([[ +#include +#include +#include +#include +#include + ]], [[ +int s, one = 1; +if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) + err(1, "socket"); +if (pledge("stdio", NULL) == -1) + err(1, "pledge"); +if (setsockopt(s, IPPROTO_IP, IP_TOS, &one, sizeof(one)) == -1) + err(1, "setsockopt"); + ]])], + [ AC_MSG_RESULT([yes]) ], [ + AC_MSG_RESULT([no]) + need_pledge_inet=1 + ], + [ AC_MSG_WARN([cross compiling: cannot test]) ]) ;; *-*-solaris*) if test "x$withval" != "xno" ; then @@ -1102,9 +1218,6 @@ mips-sony-bsd|mips-sony-newsos4) AC_DEFINE([PAM_SUN_CODEBASE]) AC_DEFINE([LOGIN_NEEDS_UTMPX]) AC_DEFINE([PAM_TTY_KLUDGE]) - AC_DEFINE([SSHPAM_CHAUTHTOK_NEEDS_RUID], [1], - [Define if pam_chauthtok wants real uid set - to the unpriv'ed user]) AC_DEFINE([LOCKED_PASSWD_STRING], ["*LK*"]) # Pushing STREAMS modules will cause sshd to acquire a controlling tty. AC_DEFINE([SSHD_ACQUIRES_CTTY], [1], @@ -1367,6 +1480,14 @@ AC_RUN_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ exit(0); ]])], [ AC_MSG_WARN([cross compiling: not checking compiler sanity]) ] ) +dnl Finish up special pledge(2) handling from above. +if test -z "$need_pledge_inet" ; then + AC_DEFINE_UNQUOTED([PLEDGE_EXTRA_INET], []) +else + AC_DEFINE_UNQUOTED([PLEDGE_EXTRA_INET], ["inet "], + [need inet in pledge for setsockopt IP_TOS]) +fi + dnl Checks for header files. # Checks for libraries. AC_CHECK_FUNC([setsockopt], , [AC_CHECK_LIB([socket], [setsockopt])]) @@ -1415,6 +1536,11 @@ AC_CHECK_FUNC([getspnam], , AC_SEARCH_LIBS([basename], [gen], [AC_DEFINE([HAVE_BASENAME], [1], [Define if you have the basename function.])]) +dnl sqrt() only used in unit tests. +AC_CHECK_FUNC([sqrt], , + [AC_CHECK_LIB([m], [sqrt], [TESTLIBS="$TESTLIBS -lm"])]) +AC_SUBST([TESTLIBS]) + dnl zlib defaults to enabled zlib=yes AC_ARG_WITH([zlib], @@ -1580,6 +1706,15 @@ else [Define to rpl_calloc if the replacement function should be used.]) fi +dnl Figure out if we have a system glob, and if so if we can use it. +AC_CHECK_FUNCS([glob], + [ AC_CHECK_HEADERS([glob.h], + [use_system_glob=yes], + [use_system_glob=no]) + ], + use_system_glob=no +) + # Check for ALTDIRFUNC glob() extension AC_MSG_CHECKING([for GLOB_ALTDIRFUNC support]) AC_EGREP_CPP([FOUNDIT], @@ -1597,6 +1732,7 @@ AC_EGREP_CPP([FOUNDIT], ], [ AC_MSG_RESULT([no]) + use_system_glob=no ] ) @@ -1611,7 +1747,9 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) -]) + use_system_glob=no + ] +) # Check for g.gl_statv glob() extension AC_MSG_CHECKING([for gl_statv and GLOB_KEEPSTAT extensions for glob]) @@ -1629,10 +1767,30 @@ g.gl_statv = NULL; AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) + use_system_glob=no + ] +) -]) +AC_CHECK_DECLS([GLOB_NOMATCH], , [use_system_glob=no], [#include ]) + +if test "x$broken_glob" = "xyes"; then + AC_DEFINE([BROKEN_GLOB], [1], [Do not use system glob]) + use_system_glob=no +fi -AC_CHECK_DECLS([GLOB_NOMATCH], , , [#include ]) +dnl If we don't have a system glob, or we do but we're not using it, then +dnl create a glob.h shim so we don't have to sprinkle ifdefs everywhere. +AC_MSG_CHECKING([if we can use the system glob]) +if test "x$use_system_glob" = "xyes" ; then + AC_MSG_RESULT([yes]) + # Remove any old shims. + rm -f "$COMPATINCLUDESDIR/glob.h" +else + AC_MSG_RESULT([no]) + COMPATINCLUDES="$COMPATINCLUDESDIR" + mkdir -p "$COMPATINCLUDES" + echo '#include "openbsd-compat/glob.h"' >$COMPATINCLUDES/glob.h +fi AC_CHECK_DECL([VIS_ALL], , AC_DEFINE(BROKEN_STRNVIS, 1, [missing VIS_ALL]), [#include ]) @@ -1661,6 +1819,12 @@ AC_RUN_IFELSE( ] ) +AC_CHECK_MEMBERS([struct dirent.d_type], [], [], [[ +#ifdef HAVE_DIRENT_H +#include +#endif +]]) + AC_MSG_CHECKING([for /proc/pid/fd directory]) if test -d "/proc/$$/fd" ; then AC_DEFINE([HAVE_PROC_PID], [1], [Define if you have /proc/$pid/fd]) @@ -1772,6 +1936,48 @@ AC_ARG_WITH([libedit], fi ] ) +# Check whether user wants wtmpdb support +WTMPDB_MSG="no" +AC_ARG_WITH([wtmpdb], + [ --with-wtmpdb[[=PATH]] Enable wtmpdb support for sshd], + [ if test "x$withval" != "xno" ; then + if test "x$withval" = "xyes" ; then + if test "x$PKGCONFIG" != "xno"; then + AC_MSG_CHECKING([if $PKGCONFIG knows about wtmpdb]) + if "$PKGCONFIG" libwtmpdb; then + AC_MSG_RESULT([yes]) + use_pkgconfig_for_libwtmpdb=yes + else + AC_MSG_RESULT([no]) + fi + fi + else + CPPFLAGS="$CPPFLAGS -I${withval}/include" + if test -n "${rpath_opt}"; then + LDFLAGS="-L${withval}/lib ${rpath_opt}${withval}/lib ${LDFLAGS}" + else + LDFLAGS="-L${withval}/lib ${LDFLAGS}" + fi + fi + if test "x$use_pkgconfig_for_libwtmpdb" = "xyes"; then + LIBWTMPDB=`$PKGCONFIG --libs libwtmpdb` + CPPFLAGS="$CPPFLAGS `$PKGCONFIG --cflags libwtmpdb`" + else + LIBWTMPDB="-lwtmpdb" + fi + OTHERLIBS=`echo $LIBWTMPDB | sed 's/-lwtmpdb//'` + AC_CHECK_LIB([wtmpdb], [wtmpdb_login], + [ AC_DEFINE([USE_WTMPDB], [1], [Use libwtmpdb for sshd]) + WTMPDB_MSG="yes" + AC_SUBST([LIBWTMPDB]) + ], + [ AC_MSG_ERROR([libwtmpdb not found]) ], + [ $OTHERLIBS ] + ) + fi ] +) + + AUDIT_MODULE=none AC_ARG_WITH([audit], [ --with-audit=module Enable audit support (modules=debug,bsm,linux)], @@ -1923,6 +2129,7 @@ AC_CHECK_FUNCS([ \ fnmatch \ freeaddrinfo \ freezero \ + fstatat \ fstatfs \ fstatvfs \ futimes \ @@ -1933,7 +2140,6 @@ AC_CHECK_FUNCS([ \ getline \ getnameinfo \ getopt \ - getpagesize \ getpeereid \ getpeerucred \ getpgid \ @@ -1942,7 +2148,6 @@ AC_CHECK_FUNCS([ \ getrandom \ getsid \ getttyent \ - glob \ group_from_gid \ inet_aton \ inet_ntoa \ @@ -1957,7 +2162,9 @@ AC_CHECK_FUNCS([ \ memmove \ memset_s \ mkdtemp \ + mmap \ ngetaddrinfo \ + nlist \ nsleep \ ogetaddrinfo \ openlog_r \ @@ -2018,7 +2225,9 @@ AC_CHECK_FUNCS([ \ timegm \ timingsafe_bcmp \ truncate \ + unlinkat \ unsetenv \ + unveil \ updwtmpx \ utimensat \ user_from_uid \ @@ -2029,6 +2238,19 @@ AC_CHECK_FUNCS([ \ warn \ ]) +AC_MSG_CHECKING([whether compiler supports __builtin_popcount]) +AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #include + ]], + [[ int x = 123, y; + y = __builtin_popcount(123); + exit(y == 6 ? 0 : -1); ]])], + [ AC_MSG_RESULT([yes]) ], [ + AC_MSG_RESULT([no]) + AC_DEFINE([MISSING_BUILTIN_POPCOUNT], [1], [Define if your compiler lacks __builtin_popcount]) + ] +) + AC_CHECK_DECLS([bzero, memmem]) dnl Wide character support. @@ -2084,14 +2306,10 @@ AC_ARG_WITH([security-key-builtin], [ enable_sk_internal=$withval ] ) -enable_dsa= -AC_ARG_ENABLE([dsa-keys], - [ --enable-dsa-keys enable DSA key support [no]], - [ - if test "x$enableval" != "xno" ; then - enable_dsa=1 - fi - ] +enable_sk_standalone= +AC_ARG_WITH([security-key-standalone], + [ --with-security-key-standalone build standalone sk-libfido2 SecurityKeyProvider], + [ enable_sk_standalone=$withval ] ) AC_SEARCH_LIBS([dlopen], [dl]) @@ -2190,6 +2408,11 @@ AC_CHECK_DECLS([offsetof], , , [ #include ]) +AC_CHECK_DECLS([INFINITY], , + AC_CHECK_DECLS(__builtin_inff), + [#include ] +) + # extra bits for select(2) AC_CHECK_DECLS([howmany, NFDBITS], [], [], [[ #include @@ -2400,6 +2623,9 @@ fi # This is only useful for when BROKEN_SNPRINTF AC_MSG_CHECKING([whether snprintf can declare const char *fmt]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifdef _FORTIFY_SOURCE +#undef _FORTIFY_SOURCE +#endif #include int snprintf(char *a, size_t b, const char *c, ...) { return 0; } ]], [[ @@ -2791,8 +3017,15 @@ nocrypto_saved_LIBS="$LIBS" if test "x$openssl" = "xyes" ; then LIBS="-lcrypto $LIBS" CHANNELLIBS="-lcrypto $CHANNELLIBS" - AC_TRY_LINK_FUNC([RAND_add], , - [AC_MSG_ERROR([*** working libcrypto not found, check config.log])]) + AC_TRY_LINK_FUNC([RAND_add], , [ + # As of early 2026, BoringSSL libcrypto needs -lstdc++ for + # destructors so try that before giving up. + LIBS="$LIBS -lstdc++" + CHANNELLIBS="$CHANNELLIBS -lstdc++" + AC_TRY_LINK_FUNC([RAND_add], , [ + AC_MSG_ERROR([*** working libcrypto not found, check config.log]) + ]) + ]) AC_CHECK_HEADER([openssl/opensslv.h], , [AC_MSG_ERROR([*** OpenSSL headers missing - please install first or check config.log ***])]) @@ -2890,8 +3123,8 @@ if test "x$openssl" = "xyes" ; then *) ;; # Assume all other versions are good. esac ;; - 30*) - # OpenSSL 3; we use the 1.1x API + 30*|40*) + # OpenSSL 3 & 4; we use the 1.1x API # https://openssl.org/policies/general/versioning-policy.html CPPFLAGS="$CPPFLAGS -DOPENSSL_API_COMPAT=0x10100000L" ;; @@ -2981,7 +3214,6 @@ if test "x$openssl" = "xyes" ; then AC_CHECK_FUNCS([ \ BN_is_prime_ex \ DES_crypt \ - DSA_generate_parameters_ex \ EVP_DigestSign \ EVP_DigestVerify \ EVP_DigestFinal_ex \ @@ -2994,17 +3226,12 @@ if test "x$openssl" = "xyes" ; then RSA_get_default_method \ ]) - # OpenSSL_add_all_algorithms may be a macro. - AC_CHECK_FUNC(OpenSSL_add_all_algorithms, - AC_DEFINE(HAVE_OPENSSL_ADD_ALL_ALGORITHMS, 1, [as a function]), - AC_CHECK_DECL(OpenSSL_add_all_algorithms, - AC_DEFINE(HAVE_OPENSSL_ADD_ALL_ALGORITHMS, 1, [as a macro]), , - [[#include ]] - ) - ) - # LibreSSL/OpenSSL API differences AC_CHECK_FUNCS([ \ + EC_POINT_get_affine_coordinates \ + EC_POINT_get_affine_coordinates_GFp \ + EC_POINT_set_affine_coordinates \ + EC_POINT_set_affine_coordinates_GFp \ EVP_CIPHER_CTX_iv \ EVP_CIPHER_CTX_iv_noconst \ EVP_CIPHER_CTX_get_iv \ @@ -3187,6 +3414,10 @@ if test "x$openssl" = "xyes" ; then [AC_LANG_PROGRAM([[ #include #include + #include + #ifdef OPENSSL_NO_EC + # error "OpenSSL has no EC support." + #endif ]], [[ unsigned char buf[64]; memset(buf, 0, sizeof(buf)); @@ -3202,34 +3433,17 @@ if test "x$openssl" = "xyes" ; then AC_MSG_RESULT([no]) ] ) - - openssl_dsa=no - if test ! -z "$enable_dsa" ; then - AC_CHECK_DECLS([OPENSSL_NO_DSA], [], [ - AC_CHECK_DECLS([OPENSSL_IS_BORINGSSL], [], - [ openssl_dsa=yes ], - [ #include ] - ) - ], - [ #include ] - ) - AC_MSG_CHECKING([whether to enable DSA key support]) - if test "x$openssl_dsa" = "xno"; then - AC_MSG_ERROR([DSA requested but not supported by OpenSSL]) - else - AC_MSG_RESULT([yes]) - AC_DEFINE([WITH_DSA], [1], - [DSA keys explicitly enabled]) - fi - fi fi # PKCS11/U2F depend on OpenSSL and dlopen(). enable_pkcs11=yes enable_sk=yes -if test "x$openssl" != "xyes" ; then - enable_pkcs11="disabled; missing libcrypto" -fi + +AC_CHECK_DECL([OPENSSL_IS_AWSLC], + [enable_pkcs11="disabled; PKCS#11 not supported with AWS-LC"], + [], + [#include ] +) if test "x$ac_cv_func_dlopen" != "xyes" ; then enable_pkcs11="disabled; missing dlopen(3)" enable_sk="disabled; missing dlopen(3)" @@ -3321,6 +3535,16 @@ if test "x$enable_sk" = "xyes" -a "x$enable_sk_internal" != "xno" ; then fi fi +# Check for standalone SecurityKeyProvider +AC_MSG_CHECKING([whether to build standalone sk-libfido2]) +if test "x$enable_sk_standalone" = "xyes" ; then + AC_MSG_RESULT([yes]) + AC_SUBST([SK_STANDALONE], [sk-libfido2$SHLIBEXT]) +else + AC_MSG_RESULT([no]) + AC_SUBST([SK_STANDALONE], [""]) +fi + AC_CHECK_FUNCS([ \ arc4random \ arc4random_buf \ @@ -3610,10 +3834,28 @@ AC_CHECK_TYPES([nfds_t], , , [ #endif ]) +if test "x$ac_cv_type_nfds_t" != "xyes"; then + AC_MSG_CHECKING([if poll nfds_t is unsigned long]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#ifdef HAVE_POLL_H +#include +#endif +#ifdef HAVE_SYS_POLL_H +#include +#endif + int poll(struct pollfd *, unsigned long, int timeout); + ]], [[return poll(0, 0, 0);]])], + [AC_MSG_RESULT([yes]) + AC_DEFINE(POLL_NFDS_T_ULONG, 1, [Define if poll 2nd arg is ulong])], + [AC_MSG_RESULT([no])] + ) +fi + # Decide which sandbox style to use sandbox_arg="" AC_ARG_WITH([sandbox], - [ --with-sandbox=style Specify privilege separation sandbox (no, capsicum, darwin, rlimit, seccomp_filter, systrace, pledge)], + [ --with-sandbox=style Specify privilege separation sandbox (no, capsicum, darwin, rlimit, seccomp_filter)], [ if test "x$withval" = "xyes" ; then sandbox_arg="" @@ -3730,19 +3972,7 @@ if test "x$sandbox_arg" != "xno"; then ) fi -if test "x$sandbox_arg" = "xpledge" || \ - ( test -z "$sandbox_arg" && test "x$ac_cv_func_pledge" = "xyes" ) ; then - test "x$ac_cv_func_pledge" != "xyes" && \ - AC_MSG_ERROR([pledge sandbox requires pledge(2) support]) - SANDBOX_STYLE="pledge" - AC_DEFINE([SANDBOX_PLEDGE], [1], [Sandbox using pledge(2)]) -elif test "x$sandbox_arg" = "xsystrace" || \ - ( test -z "$sandbox_arg" && test "x$have_systr_policy_kill" = "x1" ) ; then - test "x$have_systr_policy_kill" != "x1" && \ - AC_MSG_ERROR([systrace sandbox requires systrace headers and SYSTR_POLICY_KILL support]) - SANDBOX_STYLE="systrace" - AC_DEFINE([SANDBOX_SYSTRACE], [1], [Sandbox using systrace(4)]) -elif test "x$sandbox_arg" = "xdarwin" || \ +if test "x$sandbox_arg" = "xdarwin" || \ ( test -z "$sandbox_arg" && test "x$ac_cv_func_sandbox_init" = "xyes" && \ test "x$ac_cv_header_sandbox_h" = "xyes") ; then test "x$ac_cv_func_sandbox_init" != "xyes" -o \ @@ -4361,7 +4591,11 @@ int main(void) long long num = 0x7fffffffffffffffll; #endif strcpy(expected_out, "9223372036854775807"); +#if (SIZEOF_LONG_INT == 8) + snprintf(buf, mazsize, "%ld", num); +#else snprintf(buf, mazsize, "%lld", num); +#endif if(strcmp(buf, expected_out) != 0) exit(1); exit(0); @@ -5652,15 +5886,17 @@ AC_PATH_PROG([DROPBEAR], [dropbear]) AC_PATH_PROG([DBCLIENT], [dbclient]) AC_PATH_PROG([DROPBEARKEY], [dropbearkey]) AC_PATH_PROG([DROPBEARCONVERT], [dropbearconvert]) +AC_PATH_PROG([TMUX], [tmux]) CFLAGS="${CFLAGS} ${CFLAGS_AFTER}" LDFLAGS="${LDFLAGS} ${LDFLAGS_AFTER}" # Make a copy of CFLAGS/LDFLAGS without PIE options. -LDFLAGS_NOPIE=`echo "$LDFLAGS" | sed 's/ -pie//'` -CFLAGS_NOPIE=`echo "$CFLAGS" | sed 's/ -fPIE//'` +LDFLAGS_NOPIE=`echo "$LDFLAGS" | sed 's/^-pie //;s/ -pie//g'` +CFLAGS_NOPIE=`echo "$CFLAGS" | sed 's/^-fPIE //;s/ -fPIE//g'` AC_SUBST([LDFLAGS_NOPIE]) AC_SUBST([CFLAGS_NOPIE]) +AC_SUBST([COMPATINCLUDES]) AC_EXEEXT AC_CONFIG_FILES([Makefile buildpkg.sh opensshd.init openssh.xml \ diff --git a/contrib/Makefile b/contrib/Makefile index 45d878b..1482783 100644 --- a/contrib/Makefile +++ b/contrib/Makefile @@ -1,7 +1,7 @@ PKG_CONFIG = pkg-config all: - @echo "Valid targets: gnome-ssh-askpass1 gnome-ssh-askpass2 gnome-ssk-askpass3" + @echo "Valid targets: gnome-ssh-askpass1 gnome-ssh-askpass2 gnome-ssk-askpass3 gnome-ssh-askpass4" gnome-ssh-askpass1: gnome-ssh-askpass1.c $(CC) $(CFLAGS) `gnome-config --cflags gnome gnomeui` \ @@ -18,5 +18,10 @@ gnome-ssh-askpass3: gnome-ssh-askpass3.c gnome-ssh-askpass3.c -o gnome-ssh-askpass3 \ `$(PKG_CONFIG) --libs gtk+-3.0 x11` +gnome-ssh-askpass4: gnome-ssh-askpass4.c + $(CC) $(CFLAGS) `$(PKG_CONFIG) --cflags gcr-4 gio-2.0` \ + gnome-ssh-askpass4.c -o gnome-ssh-askpass4 \ + `$(PKG_CONFIG) --libs gcr-4 gio-2.0` + clean: rm -f *.o gnome-ssh-askpass gnome-ssh-askpass[123] diff --git a/contrib/README b/contrib/README index 60e19ba..614152a 100644 --- a/contrib/README +++ b/contrib/README @@ -30,10 +30,12 @@ ssh-copy-id: Phil Hands' shell script to automate the process of adding your public key to a remote machine's ~/.ssh/authorized_keys file. -gnome-ssh-askpass[12]: +gnome-ssh-askpass[1234]: -A GNOME and Gtk2 passphrase requesters. Use "make gnome-ssh-askpass1" or -"make gnome-ssh-askpass2" to build. +Graphical passhrase requesters. Use "make gnome-ssh-askpass1" to build +a variant for ancient GNOME desktop, "make gnome-ssh-askpass2" +for a GTK 2-based one, "make gnome-ssh-askpass3" for a GTK 3-based one, +or "make gnome-ssh-askpass4" for a version for modern GNOME. sshd.pam.generic: diff --git a/contrib/cygwin/ssh-user-config b/contrib/cygwin/ssh-user-config index 6fa4bb3..35802d0 100644 --- a/contrib/cygwin/ssh-user-config +++ b/contrib/cygwin/ssh-user-config @@ -58,7 +58,7 @@ create_identity() { else ssh-keygen -t "${type}" -f "${pwdhome}/.ssh/${file}" > /dev/null fi - if csih_request "Do you want to use this identity to login to this machine?" + if csih_request "Do you want to use this identity to log in to this machine?" then csih_inform "Adding to ${pwdhome}/.ssh/authorized_keys" cat "${pwdhome}/.ssh/${file}.pub" >> "${pwdhome}/.ssh/authorized_keys" @@ -246,9 +246,8 @@ done check_user_homedir check_user_dot_ssh_dir create_identity id_rsa rsa "SSH2 RSA" -create_identity id_dsa dsa "SSH2 DSA" +create_identity id_ed25519 ed25519 "SSH2 Ed25519" create_identity id_ecdsa ecdsa "SSH2 ECDSA" -create_identity identity rsa1 "(deprecated) SSH1 RSA" fix_authorized_keys_perms echo diff --git a/contrib/gnome-ssh-askpass4.c b/contrib/gnome-ssh-askpass4.c new file mode 100644 index 0000000..182bce0 --- /dev/null +++ b/contrib/gnome-ssh-askpass4.c @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2000-2002 Damien Miller. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* GCR support by Jan Tojnar */ + +/* + * This is a simple SSH passphrase grabber for GNOME. To use it, set the + * environment variable SSH_ASKPASS to point to the location of + * gnome-ssh-askpass before calling "ssh-add < /dev/null". + */ + +/* + * Known problems: + * - This depends on unstable libgcr features + * - long key fingerprints may be truncted: + * https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/6781 + */ + +/* + * Compile with: + * + * cc -Wall `pkg-config --cflags gcr-4 gio-2.0` \ + * gnome-ssh-askpass4.c -o gnome-ssh-askpass \ + * `pkg-config --libs gcr-4 gio-2.0` + * + */ + +#include +#include + +#include + +#define GCR_API_SUBJECT_TO_CHANGE 1 +#include + +typedef enum _PromptType { + PROMPT_ENTRY, + PROMPT_CONFIRM, + PROMPT_NONE, +} PromptType; + +typedef struct _PromptState { + GApplication *app; + char* message; + PromptType type; + int exit_status; +} PromptState; + +static PromptState * +prompt_state_new(GApplication *app, char* message, PromptType type) +{ + PromptState *state = g_malloc(sizeof(PromptState)); + state->app = g_object_ref(app); + state->message = g_strdup(message); + state->type = type; + state->exit_status = -1; + return state; +} + +static void +prompt_state_free(PromptState *state) +{ + g_clear_object(&state->app); + g_free(state->message); + g_free(state); +} + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(PromptState, prompt_state_free) + +static void +prompt_password_done(GObject *source_object, GAsyncResult *res, + gpointer user_data) +{ + GcrPrompt *prompt = GCR_PROMPT(source_object); + PromptState *state = user_data; + g_autoptr(GError) error = NULL; + + /* + * “The returned password is valid until the next time a method + * is called to display another prompt.” + */ + const char *pw = gcr_prompt_password_finish(prompt, res, &error); + + if ((!pw && !error) || (error && error->code == G_IO_ERROR_CANCELLED)) { + /* Operation was cancelled or timed out. */ + state->exit_status = -1; + } else if (error) { + warnx("Failed to prompt for ssh-askpass: %s", error->message); + state->exit_status = 1; + } else { + /* Report passphrase if user selected Continue. */ + g_autofree char *local = g_locale_from_utf8(pw, strlen(pw), + NULL, NULL, NULL); + + if (local != NULL) { + puts(local); + memset(local, '\0', strlen(local)); + } else { + puts(pw); + } + state->exit_status = 0; + } + + g_application_release(state->app); +} + +static void +prompt_confirm_done(GObject *source_object, GAsyncResult *res, + gpointer user_data) +{ + GcrPrompt *prompt = GCR_PROMPT(source_object); + PromptState *state = user_data; + g_autoptr(GError) error = NULL; + + GcrPromptReply reply = gcr_prompt_confirm_finish(prompt, res, &error); + if (error) { + if (error->code == G_IO_ERROR_CANCELLED) { + /* Operation was cancelled or timed out. */ + state->exit_status = -1; + } else { + state->exit_status = 1; + warnx("Failed to prompt for ssh-askpass: %s", + error->message); + } + } else if (reply == GCR_PROMPT_REPLY_CONTINUE || + state->type == PROMPT_NONE) { + /* + * Since Gcr doesn’t yet support one button message + * boxes treat Cancel the same as Continue. + */ + state->exit_status = 0; + } else { + /* GCR_PROMPT_REPLY_CANCEL */ + state->exit_status = -1; + } + + g_application_release(state->app); +} + +static int +command_line(GApplication* app, G_GNUC_UNUSED GApplicationCommandLine *cmdline, + gpointer user_data) +{ + PromptState *state = user_data; + + /* Prevent app from exiting while waiting for the async callback. */ + g_application_hold(app); + + /* Wait indefinitely. */ + int timeout_seconds = -1; + g_autoptr(GError) error = NULL; + GcrPrompt* prompt = gcr_system_prompt_open(timeout_seconds, NULL, &error); + + if (!prompt) { + if (error->code == GCR_SYSTEM_PROMPT_IN_PROGRESS) { + /* + * This means the timeout elapsed, but no prompt + * was ever shown. + */ + warnx("Timeout: the Gcr system prompter was " + "already in use."); + } else { + warnx("Couldn’t create prompt for ssh-askpass: %s", + error->message); + } + + return 1; + } + + gcr_prompt_set_message(prompt, "OpenSSH"); + gcr_prompt_set_description(prompt, state->message); + + /* + * XXX: Remove the Cancel button for PROMPT_NONE when GCR + * supports that. + */ + if (state->type == PROMPT_ENTRY) { + gcr_prompt_password_async(prompt, NULL, prompt_password_done, state); + } else { + gcr_prompt_confirm_async(prompt, NULL, prompt_confirm_done, state); + } + + /* The exit status will be changed in the async callbacks. */ + return 1; +} + +int +main(int argc, char **argv) +{ + g_autoptr(GApplication) app = g_application_new( + "com.openssh.gnome-ssh-askpass4", + G_APPLICATION_HANDLES_COMMAND_LINE); + g_autofree char *message = NULL; + + if (argc > 1) { + message = g_strjoinv(" ", argv + 1); + } else { + message = g_strdup("Enter your OpenSSH passphrase:"); + } + + const char *prompt_mode = getenv("SSH_ASKPASS_PROMPT"); + PromptType type = PROMPT_ENTRY; + if (prompt_mode != NULL) { + if (strcasecmp(prompt_mode, "confirm") == 0) { + type = PROMPT_CONFIRM; + } else if (strcasecmp(prompt_mode, "none") == 0) { + type = PROMPT_NONE; + } + } + + g_autoptr(PromptState) state = prompt_state_new(app, message, type); + + g_signal_connect(app, "command-line", G_CALLBACK(command_line), state); + + /* + * Since we are calling g_application_hold, we cannot use + * g_application_command_line_set_exit_status. + * To change the exit status returned by g_application_run: + * “If the commandline invocation results in the mainloop running + * (ie: because the use-count of the application increased to a + * non-zero value) then the application is considered to have been + * ‘successful’ in a certain sense, and the exit status is always + * zero.” + */ + (void)(g_application_run(app, argc, argv)); + + return state->exit_status; +} diff --git a/contrib/redhat/openssh.spec b/contrib/redhat/openssh.spec index 34fce8c..735d532 100644 --- a/contrib/redhat/openssh.spec +++ b/contrib/redhat/openssh.spec @@ -1,4 +1,4 @@ -%global ver 9.9p2 +%global ver 10.3p1 %global rel 1%{?dist} # OpenSSH privilege separation requires a user & group ID @@ -23,14 +23,6 @@ # Use GTK2 instead of GNOME in gnome-ssh-askpass %global gtk2 1 -# Use build6x options for older RHEL builds -# RHEL 7 not yet supported -%if 0%{?rhel} > 6 -%global build6x 0 -%else -%global build6x 1 -%endif - %global without_openssl 0 # build without openssl where 1.1.1 is not available %if %{defined fedora} && 0%{?fedora} <= 28 @@ -53,14 +45,6 @@ # rpm -ba|--rebuild --define 'no_gtk2 1' %{?no_gtk2:%global gtk2 0} -# Is this a build for RHL 6.x or earlier? -%{?build_6x:%global build6x 1} - -# If this is RHL 6.x, the default configuration has sysconfdir in /usr/etc. -%if %{build6x} -%global _sysconfdir /etc -%endif - # Options for static OpenSSL link: # rpm -ba|--rebuild --define "static_openssl 1" %{?static_openssl:%global static_libcrypto 1} @@ -93,21 +77,13 @@ License: BSD Group: Applications/Internet BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot Obsoletes: ssh -%if %{build6x} -PreReq: initscripts >= 5.00 -%else Requires: initscripts >= 5.20 -%endif BuildRequires: perl %if ! %{without_openssl} BuildRequires: openssl-devel >= 1.1.1 %endif BuildRequires: /bin/login -%if ! %{build6x} BuildRequires: glibc-devel, pam -%else -BuildRequires: /usr/include/security/pam_appl.h -%endif %if ! %{no_x11_askpass} BuildRequires: /usr/include/X11/Xlib.h # Xt development tools @@ -136,9 +112,7 @@ Summary: The OpenSSH server daemon. Group: System Environment/Daemons Obsoletes: ssh-server Requires: openssh = %{version}-%{release}, chkconfig >= 0.9 -%if ! %{build6x} Requires: /etc/pam.d/system-auth -%endif %package askpass Summary: A passphrase dialog for OpenSSH and X. @@ -307,20 +281,6 @@ if [ "$1" != 0 -a -r /var/run/sshd.pid ] ; then touch /var/run/sshd.restart fi -%triggerun server -- openssh-server < 2.5.0p1 -# Count the number of HostKey and HostDsaKey statements we have. -gawk 'BEGIN {IGNORECASE=1} - /^hostkey/ || /^hostdsakey/ {sawhostkey = sawhostkey + 1} - END {exit sawhostkey}' /etc/ssh/sshd_config -# And if we only found one, we know the client was relying on the old default -# behavior, which loaded the the SSH2 DSA host key when HostDsaKey wasn't -# specified. Now that HostKey is used for both SSH1 and SSH2 keys, specifying -# one nullifies the default, which would have loaded both. -if [ $? -eq 1 ] ; then - echo HostKey /etc/ssh/ssh_host_rsa_key >> /etc/ssh/sshd_config - echo HostKey /etc/ssh/ssh_host_dsa_key >> /etc/ssh/sshd_config -fi - %triggerpostun server -- ssh-server if [ "$1" != 0 ] ; then /sbin/chkconfig --add sshd @@ -393,6 +353,7 @@ fi %defattr(-,root,root) %dir %attr(0111,root,root) %{_var}/empty/sshd %attr(0755,root,root) %{_sbindir}/sshd +%attr(0755,root,root) %{_libexecdir}/openssh/sshd-auth %attr(0755,root,root) %{_libexecdir}/openssh/sshd-session %attr(0755,root,root) %{_libexecdir}/openssh/sftp-server %attr(0644,root,root) %{_mandir}/man8/sshd.8* @@ -427,6 +388,8 @@ fi - Remove reference of dropped sshd.pam.old file - Update openssl-devel dependency to require >= 1.1.1 - Build with --without-openssl elsewhere +- Remove ancient build6x config, intended for RHL 6.x + (the distro predating Fedora, not RHEL) * Thu Oct 28 2021 Damien Miller - Remove remaining traces of --with-md5-passwords diff --git a/contrib/redhat/sshd.init b/contrib/redhat/sshd.init index 8ee5fcd..b825459 100755 --- a/contrib/redhat/sshd.init +++ b/contrib/redhat/sshd.init @@ -41,7 +41,7 @@ start() /usr/bin/ssh-keygen -A if [ -x /sbin/restorecon ]; then /sbin/restorecon /etc/ssh/ssh_host_rsa_key.pub - /sbin/restorecon /etc/ssh/ssh_host_dsa_key.pub + /sbin/restorecon /etc/ssh/ssh_host_ed25519_key.pub /sbin/restorecon /etc/ssh/ssh_host_ecdsa_key.pub fi diff --git a/contrib/ssh-copy-id b/contrib/ssh-copy-id index dcf5798..afb9bec 100644 --- a/contrib/ssh-copy-id +++ b/contrib/ssh-copy-id @@ -1,12 +1,14 @@ #!/bin/sh -# Copyright (c) 1999-2024 Philip Hands +# Copyright (c) 1999-2025 Philip Hands +# 2025 Denis Ovsienko +# 2024 Frank Fischer # 2021 Carlos Rodríguez Gili # 2020 Matthias Blümel # 2017 Sebastien Boyron # 2013 Martin Kletzander # 2010 Adeodato =?iso-8859-1?Q?Sim=F3?= -# 2010 Eric Moret +# 2010 Eric Moret # 2009 Xr # 2007 Justin Pryzby # 2004 Reini Urban @@ -284,14 +286,17 @@ installkeys_sh() { # the -z `tail ...` checks for a trailing newline. The echo adds one if was missing # the cat adds the keys we're getting via STDIN # and if available restorecon is used to restore the SELinux context - # OpenWrt has a special case for root only. - INSTALLKEYS_SH=$(tr '\t\n' ' ' <<-EOF + # OpenWrt has a special case for root/UID:0. Haiku is also special. + INSTALLKEYS_SH=$(tr -s '\t\n' ' ' <<-EOF $SET_X cd; umask 077; AUTH_KEY_FILE="${TARGET_PATH}"; - [ -f /etc/openwrt_release ] && [ "\$LOGNAME" = "root" ] && + [ -f /etc/openwrt_release ] && + { [ "\$LOGNAME" = "root" ] || [ "\$(id -u)" = "0" ]; } && AUTH_KEY_FILE=/etc/dropbear/authorized_keys; + [ "\`uname -s\`" = "Haiku" ] && + AUTH_KEY_FILE=config/settings/ssh/authorized_keys; AUTH_KEY_DIR=\`dirname "\${AUTH_KEY_FILE}"\`; mkdir -p "\${AUTH_KEY_DIR}" && { [ -z "\`tail -1c "\${AUTH_KEY_FILE}" 2>/dev/null\`" ] || diff --git a/contrib/suse/openssh.spec b/contrib/suse/openssh.spec index 1a4b7d9..1ca2db1 100644 --- a/contrib/suse/openssh.spec +++ b/contrib/suse/openssh.spec @@ -13,7 +13,7 @@ Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation Name: openssh -Version: 9.9p2 +Version: 10.3p1 URL: https://www.openssh.com/ Release: 1 Source0: openssh-%{version}.tar.gz @@ -211,6 +211,7 @@ rm -rf $RPM_BUILD_ROOT %attr(0755,root,root) %{_sbindir}/sshd %attr(0755,root,root) %dir %{_libdir}/ssh %attr(0755,root,root) %{_libdir}/ssh/sftp-server +%attr(0755,root,root) %{_libdir}/ssh/sshd-auth %attr(0755,root,root) %{_libdir}/ssh/sshd-session %attr(4711,root,root) %{_libdir}/ssh/ssh-keysign %attr(0755,root,root) %{_libdir}/ssh/ssh-pkcs11-helper diff --git a/crypto_api.h b/crypto_api.h index 8bbc3a0..f5e38b5 100644 --- a/crypto_api.h +++ b/crypto_api.h @@ -1,4 +1,4 @@ -/* $OpenBSD: crypto_api.h,v 1.9 2024/09/02 12:13:56 djm Exp $ */ +/* $OpenBSD: crypto_api.h,v 1.10 2025/10/30 23:19:33 djm Exp $ */ /* * Assembled from generated headers and source files by Markus Friedl. @@ -10,9 +10,7 @@ #include "includes.h" -#ifdef HAVE_STDINT_H -# include -#endif +#include #include typedef int8_t crypto_int8; @@ -29,8 +27,34 @@ typedef uint64_t crypto_uint64; #define crypto_hash_sha512_BYTES 64U -int crypto_hash_sha512(unsigned char *, const unsigned char *, - unsigned long long); +#ifdef WITH_OPENSSL +#include +static inline int +crypto_hash_sha512(unsigned char *out, const unsigned char *in, + unsigned long long inlen) +{ + + if (!EVP_Digest(in, inlen, out, NULL, EVP_sha512(), NULL)) + return -1; + return 0; +} +#else /* WITH_OPENSSL */ +# ifdef HAVE_SHA2_H +# include +# endif +static inline int +crypto_hash_sha512(unsigned char *out, const unsigned char *in, + unsigned long long inlen) +{ + + SHA2_CTX ctx; + + SHA512Init(&ctx); + SHA512Update(&ctx, in, inlen); + SHA512Final(out, &ctx); + return 0; +} +#endif /* WITH_OPENSSL */ #define crypto_sign_ed25519_SECRETKEYBYTES 64U #define crypto_sign_ed25519_PUBLICKEYBYTES 32U diff --git a/debian/changelog b/debian/changelog index ed4aacd..61e1f7c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,14 @@ +openssh (1:10.3p1-1deepin1) unstable; urgency=medium + + * New upstream release 10.3p1 Security fixes: * CVE-2026-35414: Fix + authorized_keys principals option handling * CVE-2026-35388: Fix + missing connection multiplexing confirmation * CVE-2026-35387: Fix + incomplete application of ECDSA algorithms * CVE-2026-35386: Fix + shell metacharacters validation in usernames * CVE-2026-35385: Fix + scp setuid/setgid bits handling + + -- deepin-ci-robot Wed, 15 Apr 2026 15:58:48 +0800 + openssh (1:9.9p2-0deepin4) unstable; urgency=medium * fix: filter Uos or uos for lsb_release -is. diff --git a/defines.h b/defines.h index c1c21ab..1d5bc04 100644 --- a/defines.h +++ b/defines.h @@ -55,7 +55,6 @@ enum /* * Definitions for IP type of service (ip_tos) */ -#include #include #ifndef IPTOS_LOWDELAY # define IPTOS_LOWDELAY 0x10 @@ -95,6 +94,9 @@ enum # define IPTOS_DSCP_CS6 0xc0 # define IPTOS_DSCP_CS7 0xe0 #endif /* IPTOS_DSCP_CS0 */ +#ifndef IPTOS_DSCP_VA +# define IPTOS_DSCP_VA 0x2c +#endif /* IPTOS_DSCP_VA */ #ifndef IPTOS_DSCP_EF # define IPTOS_DSCP_EF 0xb8 #endif /* IPTOS_DSCP_EF */ @@ -216,7 +218,9 @@ including rpc/rpc.h breaks Solaris 6 /* (or die trying) */ #ifndef HAVE_U_INT +typedef unsigned short u_short; typedef unsigned int u_int; +typedef unsigned long u_long; #endif #ifndef HAVE_INTXX_T @@ -513,6 +517,13 @@ struct winsize { } while (0) #endif +#ifndef timespeccmp +#define timespeccmp(tsp, usp, cmp) \ + (((tsp)->tv_sec == (usp)->tv_sec) ? \ + ((tsp)->tv_nsec cmp (usp)->tv_nsec) : \ + ((tsp)->tv_sec cmp (usp)->tv_sec)) +#endif + #ifndef TIMEVAL_TO_TIMESPEC #define TIMEVAL_TO_TIMESPEC(tv, ts) { \ (ts)->tv_sec = (tv)->tv_sec; \ @@ -593,6 +604,10 @@ struct winsize { # define __nonnull__(x) #endif +#if !defined(HAVE_ATTRIBUTE__NONSTRING__) && !defined(__nonstring__) +# define __nonstring__ +#endif + #ifndef OSSH_ALIGNBYTES #define OSSH_ALIGNBYTES (sizeof(int) - 1) #endif @@ -646,7 +661,9 @@ struct winsize { # endif /* WORDS_BIGENDIAN */ #endif /* BYTE_ORDER */ -#ifndef HAVE_ENDIAN_H +#if (defined(HAVE_DECL_LE32TOH) && HAVE_DECL_LE32TOH == 0) || \ + (defined(HAVE_DECL_LE64TOH) && HAVE_DECL_LE64TOH == 0) || \ + (defined(HAVE_DECL_HTOLE64) && HAVE_DECL_HTOLE64 == 0) # define openssh_swap32(v) \ (uint32_t)(((uint32_t)(v) & 0xff) << 24 | \ ((uint32_t)(v) & 0xff00) << 8 | \ @@ -662,13 +679,25 @@ struct winsize { ((uint64_t)(v) & 0xff000000000000ULL) >> 40 | \ ((uint64_t)(v) & 0xff00000000000000ULL) >> 56) # ifdef WORDS_BIGENDIAN -# define le32toh(v) (openssh_swap32(v)) -# define le64toh(v) (openssh_swap64(v)) -# define htole64(v) (openssh_swap64(v)) +# if defined(HAVE_DECL_LE32TOH) && HAVE_DECL_LE32TOH == 0 +# define le32toh(v) (openssh_swap32(v)) +# endif +# if defined(HAVE_DECL_LE64TOH) && HAVE_DECL_LE64TOH == 0 +# define le64toh(v) (openssh_swap64(v)) +# endif +# if defined(HAVE_DECL_HTOLE64) && HAVE_DECL_HTOLE64 == 0 +# define htole64(v) (openssh_swap64(v)) +# endif # else -# define le32toh(v) ((uint32_t)v) -# define le64toh(v) ((uint64_t)v) -# define htole64(v) ((uint64_t)v) +# if defined(HAVE_DECL_LE32TOH) && HAVE_DECL_LE32TOH == 0 +# define le32toh(v) ((uint32_t)v) +# endif +# if defined(HAVE_DECL_LE64TOH) && HAVE_DECL_LE64TOH == 0 +# define le64toh(v) ((uint64_t)v) +# endif +# if defined(HAVE_DECL_HTOLE64) && HAVE_DECL_HTOLE64 == 0 +# define htole64(v) ((uint64_t)v) +# endif # endif #endif @@ -954,13 +983,6 @@ struct winsize { # endif /* gcc version */ #endif /* __predict_true */ -#if defined(HAVE_GLOB_H) && defined(GLOB_HAS_ALTDIRFUNC) && \ - defined(GLOB_HAS_GL_MATCHC) && defined(GLOB_HAS_GL_STATV) && \ - defined(HAVE_DECL_GLOB_NOMATCH) && HAVE_DECL_GLOB_NOMATCH != 0 && \ - !defined(BROKEN_GLOB) -# define USE_SYSTEM_GLOB -#endif - /* * sntrup761 uses variable length arrays and c99-style declarations after code, * so only enable if the compiler supports them. @@ -970,4 +992,11 @@ struct winsize { /* The ML-KEM768 implementation also uses C89 features */ # define USE_MLKEM768X25519 1 #endif + +#if defined(HAVE_DECL_INFINITY) && HAVE_DECL_INFINITY == 0 +# if defined(HAVE_DECL___BUILTIN_INFF) && HAVE_DECL___BUILTIN_INFF == 1 +# define INFINITY __builtin_inff() +# endif +#endif + #endif /* _DEFINES_H */ diff --git a/dh.c b/dh.c index ce2eb47..b291750 100644 --- a/dh.c +++ b/dh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dh.c,v 1.74 2021/04/03 06:18:40 djm Exp $ */ +/* $OpenBSD: dh.c,v 1.76 2026/02/08 19:54:31 dtucker Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * @@ -26,6 +26,7 @@ #include "includes.h" #ifdef WITH_OPENSSL +#include "openbsd-compat/openssl-compat.h" #include #include @@ -43,8 +44,6 @@ #include "misc.h" #include "ssherr.h" -#include "openbsd-compat/openssl-compat.h" - static const char *moduli_filename; void dh_set_moduli_file(const char *filename) @@ -197,9 +196,9 @@ choose_dh(int min, int wantbits, int max) if (bestcount == 0) { fclose(f); - logit("WARNING: no suitable primes in %s", - get_moduli_filename()); - return (dh_new_group_fallback(max)); + logit("WARNING: no suitable primes (size %d/%d/%d) in %s", + min, wantbits, max, get_moduli_filename()); + return NULL; } which = arc4random_uniform(bestcount); diff --git a/digest-libc.c b/digest-libc.c index 6e77a44..b26ed27 100644 --- a/digest-libc.c +++ b/digest-libc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: digest-libc.c,v 1.7 2020/02/26 13:40:09 jsg Exp $ */ +/* $OpenBSD: digest-libc.c,v 1.10 2026/03/03 09:57:25 dtucker Exp $ */ /* * Copyright (c) 2013 Damien Miller * Copyright (c) 2014 Markus Friedl. All rights reserved. @@ -27,7 +27,6 @@ #if 0 #include -#include #endif #ifdef HAVE_SHA1_H #include @@ -51,8 +50,8 @@ #include "digest.h" typedef void md_init_fn(void *mdctx); -typedef void md_update_fn(void *mdctx, const u_int8_t *m, size_t mlen); -typedef void md_final_fn(u_int8_t[], void *mdctx); +typedef void md_update_fn(void *mdctx, const uint8_t *m, size_t mlen); +typedef void md_final_fn(uint8_t[], void *mdctx); struct ssh_digest_ctx { int alg; @@ -249,14 +248,15 @@ int ssh_digest_memory(int alg, const void *m, size_t mlen, u_char *d, size_t dlen) { struct ssh_digest_ctx *ctx = ssh_digest_start(alg); + int ret = 0; if (ctx == NULL) return SSH_ERR_INVALID_ARGUMENT; if (ssh_digest_update(ctx, m, mlen) != 0 || ssh_digest_final(ctx, d, dlen) != 0) - return SSH_ERR_INVALID_ARGUMENT; + ret = SSH_ERR_INVALID_ARGUMENT; ssh_digest_free(ctx); - return 0; + return ret; } int diff --git a/dispatch.c b/dispatch.c index 6118147..dd962a1 100644 --- a/dispatch.c +++ b/dispatch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dispatch.c,v 1.33 2023/03/05 05:34:09 dtucker Exp $ */ +/* $OpenBSD: dispatch.c,v 1.35 2026/03/03 09:57:25 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -37,11 +37,11 @@ #include "ssherr.h" int -dispatch_protocol_error(int type, u_int32_t seq, struct ssh *ssh) +dispatch_protocol_error(int type, uint32_t seq, struct ssh *ssh) { int r; - logit("dispatch_protocol_error: type %d seq %u", type, seq); + logit_f("type %d seq %u", type, seq); if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 || (r = sshpkt_put_u32(ssh, seq)) != 0 || (r = sshpkt_send(ssh)) != 0 || @@ -51,9 +51,9 @@ dispatch_protocol_error(int type, u_int32_t seq, struct ssh *ssh) } int -dispatch_protocol_ignore(int type, u_int32_t seq, struct ssh *ssh) +dispatch_protocol_ignore(int type, uint32_t seq, struct ssh *ssh) { - logit("dispatch_protocol_ignore: type %d seq %u", type, seq); + logit_f("type %d seq %u", type, seq); return 0; } @@ -88,7 +88,7 @@ ssh_dispatch_run(struct ssh *ssh, int mode, volatile sig_atomic_t *done) { int r; u_char type; - u_int32_t seqnr; + uint32_t seqnr; for (;;) { if (mode == DISPATCH_BLOCK) { diff --git a/dispatch.h b/dispatch.h index a22d774..594804c 100644 --- a/dispatch.h +++ b/dispatch.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dispatch.h,v 1.15 2019/01/19 21:45:31 djm Exp $ */ +/* $OpenBSD: dispatch.h,v 1.16 2026/03/03 09:57:25 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -36,10 +36,10 @@ enum { struct ssh; -typedef int dispatch_fn(int, u_int32_t, struct ssh *); +typedef int dispatch_fn(int, uint32_t, struct ssh *); -int dispatch_protocol_error(int, u_int32_t, struct ssh *); -int dispatch_protocol_ignore(int, u_int32_t, struct ssh *); +int dispatch_protocol_error(int, uint32_t, struct ssh *); +int dispatch_protocol_ignore(int, uint32_t, struct ssh *); void ssh_dispatch_init(struct ssh *, dispatch_fn *); void ssh_dispatch_set(struct ssh *, int, dispatch_fn *); void ssh_dispatch_range(struct ssh *, u_int, u_int, dispatch_fn *); diff --git a/dns.c b/dns.c index 9392414..0731254 100644 --- a/dns.c +++ b/dns.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dns.c,v 1.44 2023/03/10 04:06:21 dtucker Exp $ */ +/* $OpenBSD: dns.c,v 1.48 2026/03/03 09:57:25 dtucker Exp $ */ /* * Copyright (c) 2003 Wesley Griffin. All rights reserved. @@ -38,7 +38,6 @@ #include "xmalloc.h" #include "sshkey.h" -#include "ssherr.h" #include "dns.h" #include "log.h" #include "digest.h" @@ -78,7 +77,7 @@ dns_result_totext(unsigned int res) * Caller must free digest which is allocated by sshkey_fingerprint_raw(). */ static int -dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type, +dns_read_key(uint8_t *algorithm, uint8_t *digest_type, u_char **digest, size_t *digest_len, struct sshkey *key) { int r, success = 0; @@ -88,18 +87,12 @@ dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type, case KEY_RSA: *algorithm = SSHFP_KEY_RSA; break; - case KEY_DSA: - *algorithm = SSHFP_KEY_DSA; - break; case KEY_ECDSA: *algorithm = SSHFP_KEY_ECDSA; break; case KEY_ED25519: *algorithm = SSHFP_KEY_ED25519; break; - case KEY_XMSS: - *algorithm = SSHFP_KEY_XMSS; - break; default: *algorithm = SSHFP_KEY_RESERVED; /* 0 */ } @@ -132,7 +125,7 @@ dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type, * Read SSHFP parameters from rdata buffer. */ static int -dns_read_rdata(u_int8_t *algorithm, u_int8_t *digest_type, +dns_read_rdata(uint8_t *algorithm, uint8_t *digest_type, u_char **digest, size_t *digest_len, u_char *rdata, int rdata_len) { int success = 0; @@ -200,12 +193,12 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, int result; struct rrsetinfo *fingerprints = NULL; - u_int8_t hostkey_algorithm; + uint8_t hostkey_algorithm; u_char *hostkey_digest; size_t hostkey_digest_len; - u_int8_t dnskey_algorithm; - u_int8_t dnskey_digest_type; + uint8_t dnskey_algorithm; + uint8_t dnskey_digest_type; u_char *dnskey_digest; size_t dnskey_digest_len; @@ -305,9 +298,9 @@ int export_dns_rr(const char *hostname, struct sshkey *key, FILE *f, int generic, int alg) { - u_int8_t rdata_pubkey_algorithm = 0; - u_int8_t rdata_digest_type = SSHFP_HASH_RESERVED; - u_int8_t dtype; + uint8_t rdata_pubkey_algorithm = 0; + uint8_t rdata_digest_type = SSHFP_HASH_RESERVED; + uint8_t dtype; u_char *rdata_digest; size_t i, rdata_digest_len; int success = 0; diff --git a/dns.h b/dns.h index 864ab7d..ab2df06 100644 --- a/dns.h +++ b/dns.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dns.h,v 1.20 2023/02/10 04:56:30 djm Exp $ */ +/* $OpenBSD: dns.h,v 1.21 2025/08/29 03:50:38 djm Exp $ */ /* * Copyright (c) 2003 Wesley Griffin. All rights reserved. @@ -33,8 +33,7 @@ enum sshfp_types { SSHFP_KEY_RSA = 1, SSHFP_KEY_DSA = 2, SSHFP_KEY_ECDSA = 3, - SSHFP_KEY_ED25519 = 4, - SSHFP_KEY_XMSS = 5 + SSHFP_KEY_ED25519 = 4 }; enum sshfp_hashes { diff --git a/ed25519-openssl.c b/ed25519-openssl.c new file mode 100644 index 0000000..5d1e343 --- /dev/null +++ b/ed25519-openssl.c @@ -0,0 +1,207 @@ +/* $OpenBSD: ed25519-openssl.c,v 1.1 2025/10/30 20:49:10 djm Exp $ */ +/* + * Copyright (c) 2025 OpenSSH + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* + * OpenSSL-based implementation of Ed25519 crypto_sign API + * Alternative to the internal SUPERCOP-based implementation in ed25519.c + */ + +#include "includes.h" + +#ifdef OPENSSL_HAS_ED25519 + +#include + +#include +#include +#include + +#include + +#include "crypto_api.h" +#include "log.h" + +#if crypto_sign_ed25519_SECRETKEYBYTES <= crypto_sign_ed25519_PUBLICKEYBYTES +#error "crypto_sign_ed25519_SECRETKEYBYTES < crypto_sign_ed25519_PUBLICKEYBYTES" +#endif + +#define SSH_ED25519_RAW_SECRET_KEY_LEN \ + (crypto_sign_ed25519_SECRETKEYBYTES - crypto_sign_ed25519_PUBLICKEYBYTES) + +int +crypto_sign_ed25519_keypair(unsigned char *pk, unsigned char *sk) +{ + EVP_PKEY_CTX *ctx = NULL; + EVP_PKEY *pkey = NULL; + size_t pklen, sklen; + int ret = -1; + + if ((ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, NULL)) == NULL) { + debug3_f("EVP_PKEY_CTX_new_id failed"); + goto out; + } + if (EVP_PKEY_keygen_init(ctx) <= 0) { + debug3_f("EVP_PKEY_keygen_init failed"); + goto out; + } + if (EVP_PKEY_keygen(ctx, &pkey) <= 0) { + debug3_f("EVP_PKEY_keygen failed"); + goto out; + } + + /* Extract public key */ + pklen = crypto_sign_ed25519_PUBLICKEYBYTES; + if (!EVP_PKEY_get_raw_public_key(pkey, pk, &pklen)) { + debug3_f("EVP_PKEY_get_raw_public_key failed"); + goto out; + } + if (pklen != crypto_sign_ed25519_PUBLICKEYBYTES) { + debug3_f("public key length mismatch: %zu", pklen); + goto out; + } + + sklen = SSH_ED25519_RAW_SECRET_KEY_LEN; + /* Extract private key (32 bytes seed) */ + if (!EVP_PKEY_get_raw_private_key(pkey, sk, &sklen)) { + debug3_f("EVP_PKEY_get_raw_private_key failed"); + goto out; + } + if (sklen != SSH_ED25519_RAW_SECRET_KEY_LEN) { + debug3_f("private key length mismatch: %zu", sklen); + goto out; + } + + /* Append public key to secret key (SUPERCOP format compatibility) */ + memcpy(sk + sklen, pk, crypto_sign_ed25519_PUBLICKEYBYTES); + + ret = 0; +out: + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(ctx); + return ret; +} + +int +crypto_sign_ed25519(unsigned char *sm, unsigned long long *smlen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk) +{ + EVP_PKEY *pkey = NULL; + EVP_MD_CTX *mdctx = NULL; + size_t siglen; + int ret = -1; + + /* Create EVP_PKEY from secret key (first 32 bytes are the seed) */ + if ((pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519, NULL, + sk, SSH_ED25519_RAW_SECRET_KEY_LEN)) == NULL) { + debug3_f("EVP_PKEY_new_raw_private_key failed"); + goto out; + } + + /* Sign the message */ + if ((mdctx = EVP_MD_CTX_new()) == NULL) { + debug3_f("EVP_MD_CTX_new failed"); + goto out; + } + if (EVP_DigestSignInit(mdctx, NULL, NULL, NULL, pkey) != 1) { + debug3_f("EVP_DigestSignInit failed"); + goto out; + } + siglen = crypto_sign_ed25519_BYTES; + if (EVP_DigestSign(mdctx, sm, &siglen, m, mlen) != 1) { + debug3_f("EVP_DigestSign failed"); + goto out; + } + if (siglen != crypto_sign_ed25519_BYTES) { + debug3_f("signature length mismatch: %zu", siglen); + goto out; + } + + /* Append message after signature (SUPERCOP format) */ + if (mlen > ULLONG_MAX - siglen) { + debug3_f("message length overflow: siglen=%zu mlen=%llu", + siglen, mlen); + goto out; + } + memmove(sm + siglen, m, mlen); + *smlen = siglen + mlen; + + ret = 0; +out: + EVP_MD_CTX_free(mdctx); + EVP_PKEY_free(pkey); + return ret; +} + +int +crypto_sign_ed25519_open(unsigned char *m, unsigned long long *mlen, + const unsigned char *sm, unsigned long long smlen, + const unsigned char *pk) +{ + EVP_PKEY *pkey = NULL; + EVP_MD_CTX *mdctx = NULL; + int ret = -1; + const unsigned char *msg; + size_t msglen; + + if (smlen < crypto_sign_ed25519_BYTES) { + debug3_f("signed message bad length: %llu", smlen); + return -1; + } + /* Signature is first crypto_sign_ed25519_BYTES, message follows */ + msg = sm + crypto_sign_ed25519_BYTES; + msglen = smlen - crypto_sign_ed25519_BYTES; + + /* Make sure the message buffer is big enough. */ + if (*mlen < msglen) { + debug_f("message bad length: %llu", *mlen); + return -1; + } + + /* Create EVP_PKEY from public key */ + if ((pkey = EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL, + pk, crypto_sign_ed25519_PUBLICKEYBYTES)) == NULL) { + debug3_f("EVP_PKEY_new_raw_public_key failed"); + goto out; + } + + if ((mdctx = EVP_MD_CTX_new()) == NULL) { + debug3_f("EVP_MD_CTX_new failed"); + goto out; + } + if (EVP_DigestVerifyInit(mdctx, NULL, NULL, NULL, pkey) <= 0) { + debug3_f("EVP_DigestVerifyInit failed"); + goto out; + } + if (EVP_DigestVerify(mdctx, sm, crypto_sign_ed25519_BYTES, + msg, msglen) != 1) { + debug3_f("EVP_DigestVerify failed"); + goto out; + } + + /* Copy message out */ + *mlen = msglen; + memmove(m, msg, msglen); + + ret = 0; +out: + EVP_MD_CTX_free(mdctx); + EVP_PKEY_free(pkey); + return ret; +} + +#endif /* OPENSSL_HAS_ED25519 */ diff --git a/ed25519.c b/ed25519.c index 0e167ae..2452dff 100644 --- a/ed25519.c +++ b/ed25519.c @@ -11,6 +11,8 @@ #include "includes.h" +#ifndef OPENSSL_HAS_ED25519 + #include #include "crypto_api.h" @@ -2028,3 +2030,5 @@ int crypto_sign_ed25519_open( memset(m,0,smlen); return -1; } + +#endif /* OPENSSL_HAS_ED25519 */ diff --git a/entropy.c b/entropy.c index 842c66f..4e946ea 100644 --- a/entropy.c +++ b/entropy.c @@ -64,7 +64,8 @@ seed_rng(void) unsigned char buf[RANDOM_SEED_SIZE]; /* Initialise libcrypto */ - ssh_libcrypto_init(); + if (ssh_libcrypto_init() != 1) + fatal("libcrypto failed to initialize."); if (!ssh_compatible_openssl(OPENSSL_VERSION_NUMBER, OpenSSL_version_num())) @@ -107,3 +108,24 @@ seed_rng(void) } #endif /* WITH_OPENSSL */ + +void +reseed_prngs(void) +{ + uint32_t rnd[256]; + +#ifdef WITH_OPENSSL + RAND_poll(); +#endif + arc4random_stir(); /* noop on recent arc4random() implementations */ + arc4random_buf(rnd, sizeof(rnd)); /* let arc4random notice PID change */ + +#ifdef WITH_OPENSSL + RAND_seed(rnd, sizeof(rnd)); + /* give libcrypto a chance to notice the PID change */ + if ((RAND_bytes((u_char *)rnd, 1)) != 1) + fatal_f("RAND_bytes failed"); +#endif + + explicit_bzero(rnd, sizeof(rnd)); +} diff --git a/entropy.h b/entropy.h index 870164d..45d56a3 100644 --- a/entropy.h +++ b/entropy.h @@ -22,13 +22,12 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef _RANDOMS_H -#define _RANDOMS_H +#ifndef _ENTROPY_H +#define _ENTROPY_H struct sshbuf; void seed_rng(void); -void rexec_send_rng_seed(struct sshbuf *); -void rexec_recv_rng_seed(struct sshbuf *); +void reseed_prngs(void); -#endif /* _RANDOMS_H */ +#endif /* _ENTROPY_H */ diff --git a/groupaccess.c b/groupaccess.c index 80d3019..046d0e6 100644 --- a/groupaccess.c +++ b/groupaccess.c @@ -1,4 +1,4 @@ -/* $OpenBSD: groupaccess.c,v 1.17 2019/03/06 22:14:23 dtucker Exp $ */ +/* $OpenBSD: groupaccess.c,v 1.18 2024/11/04 21:59:15 jca Exp $ */ /* * Copyright (c) 2001 Kevin Steves. All rights reserved. * @@ -50,21 +50,32 @@ int ga_init(const char *user, gid_t base) { gid_t *groups_bygid; - int i, j, retry = 0; + int ongroups, i, j, retry = 0; struct group *gr; if (ngroups > 0) ga_free(); - ngroups = NGROUPS_MAX; + ongroups = ngroups = NGROUPS_MAX; #if defined(HAVE_SYSCONF) && defined(_SC_NGROUPS_MAX) - ngroups = MAX(NGROUPS_MAX, sysconf(_SC_NGROUPS_MAX)); + ongroups = ngroups = MAX(NGROUPS_MAX, sysconf(_SC_NGROUPS_MAX)); #endif groups_bygid = xcalloc(ngroups, sizeof(*groups_bygid)); while (getgrouplist(user, base, groups_bygid, &ngroups) == -1) { - if (retry++ > 0) - fatal("getgrouplist: groups list too small"); + if (ngroups <= ongroups) { + error("getgrouplist(\"%s\", %ld): failed", + user, (long)base); + free(groups_bygid); + groups_bygid = NULL; + ngroups = 0; + return 0; + } + if (retry++ > 0) { + fatal("getgrouplist(\"%s\", %ld): groups list too big " + "(have %ld, need %ld)", user, (long)base, + (long)ongroups, (long)ngroups); + } groups_bygid = xreallocarray(groups_bygid, ngroups, sizeof(*groups_bygid)); } diff --git a/gss-genr.c b/gss-genr.c index aa34b71..7088d93 100644 --- a/gss-genr.c +++ b/gss-genr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gss-genr.c,v 1.29 2024/02/01 02:37:33 djm Exp $ */ +/* $OpenBSD: gss-genr.c,v 1.31 2026/02/08 19:54:31 dtucker Exp $ */ /* * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved. diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c index a151bc1..4caac33 100644 --- a/gss-serv-krb5.c +++ b/gss-serv-krb5.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gss-serv-krb5.c,v 1.9 2018/07/09 21:37:55 markus Exp $ */ +/* $OpenBSD: gss-serv-krb5.c,v 1.10 2026/02/08 15:28:01 dtucker Exp $ */ /* * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. diff --git a/gss-serv.c b/gss-serv.c index 025a118..f9ae303 100644 --- a/gss-serv.c +++ b/gss-serv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gss-serv.c,v 1.32 2020/03/13 03:17:07 djm Exp $ */ +/* $OpenBSD: gss-serv.c,v 1.37 2026/02/11 16:57:38 dtucker Exp $ */ /* * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -30,12 +30,13 @@ #include #include +#include +#include #include #include #include -#include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "sshkey.h" #include "hostfile.h" @@ -106,7 +107,7 @@ ssh_gssapi_acquire_cred(Gssctxt *ctx) gss_create_empty_oid_set(&status, &oidset); gss_add_oid_set_member(&status, ctx->oid, &oidset); - if (gethostname(lname, HOST_NAME_MAX)) { + if (gethostname(lname, sizeof(lname))) { gss_release_oid_set(&status, &oidset); return (-1); } @@ -332,6 +333,11 @@ ssh_gssapi_cleanup_creds(void) void ssh_gssapi_storecreds(void) { + if (options.gss_deleg_creds == 0) { + debug_f("delegate credential is disabled, doing nothing"); + return; + } + if (gssapi_client.mech && gssapi_client.mech->storecreds) { (*gssapi_client.mech->storecreds)(&gssapi_client); } else diff --git a/hash.c b/hash.c deleted file mode 100644 index b4f8f6c..0000000 --- a/hash.c +++ /dev/null @@ -1,43 +0,0 @@ -/* $OpenBSD: hash.c,v 1.6 2019/11/29 00:11:21 djm Exp $ */ -/* - * Public domain. Author: Christian Weisgerber - * API compatible reimplementation of function from nacl - */ - -#include "includes.h" - -#include "crypto_api.h" - -#include - -#ifdef WITH_OPENSSL -#include - -int -crypto_hash_sha512(unsigned char *out, const unsigned char *in, - unsigned long long inlen) -{ - - if (!EVP_Digest(in, inlen, out, NULL, EVP_sha512(), NULL)) - return -1; - return 0; -} - -#else -# ifdef HAVE_SHA2_H -# include -# endif - -int -crypto_hash_sha512(unsigned char *out, const unsigned char *in, - unsigned long long inlen) -{ - - SHA2_CTX ctx; - - SHA512Init(&ctx); - SHA512Update(&ctx, in, inlen); - SHA512Final(out, &ctx); - return 0; -} -#endif /* WITH_OPENSSL */ diff --git a/hmac.c b/hmac.c index 7b58801..155e534 100644 --- a/hmac.c +++ b/hmac.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hmac.c,v 1.14 2020/02/26 13:40:09 jsg Exp $ */ +/* $OpenBSD: hmac.c,v 1.16 2026/02/14 00:18:34 jsg Exp $ */ /* * Copyright (c) 2014 Markus Friedl. All rights reserved. * @@ -22,7 +22,6 @@ #include #include -#include "sshbuf.h" #include "digest.h" #include "hmac.h" diff --git a/hostfile.c b/hostfile.c index c5669c7..033b291 100644 --- a/hostfile.c +++ b/hostfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hostfile.c,v 1.95 2023/02/21 06:48:18 dtucker Exp $ */ +/* $OpenBSD: hostfile.c,v 1.100 2025/11/25 00:57:04 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -150,8 +150,8 @@ host_hash(const char *host, const char *name_from_hostfile, u_int src_len) } /* - * Parses an RSA (number of bits, e, n) or DSA key from a string. Moves the - * pointer over the key. Skips any whitespace at the beginning and at end. + * Parses an RSA key from a string. Moves the pointer over the key. + * Skips any whitespace at the beginning and at end. */ int @@ -434,7 +434,7 @@ lookup_marker_in_hostkeys(struct hostkeys *hostkeys, int want_marker) } static int -write_host_entry(FILE *f, const char *host, const char *ip, +format_host_entry(struct sshbuf *entry, const char *host, const char *ip, const struct sshkey *key, int store_hash) { int r, success = 0; @@ -449,22 +449,50 @@ write_host_entry(FILE *f, const char *host, const char *ip, free(lhost); return 0; } - fprintf(f, "%s ", hashed_host); - } else if (ip != NULL) - fprintf(f, "%s,%s ", lhost, ip); - else { - fprintf(f, "%s ", lhost); + if ((r = sshbuf_putf(entry, "%s ", hashed_host)) != 0) + fatal_fr(r, "sshbuf_putf"); + } else if (ip != NULL) { + if ((r = sshbuf_putf(entry, "%s,%s ", lhost, ip)) != 0) + fatal_fr(r, "sshbuf_putf"); + } else { + if ((r = sshbuf_putf(entry, "%s ", lhost)) != 0) + fatal_fr(r, "sshbuf_putf"); } free(hashed_host); free(lhost); - if ((r = sshkey_write(key, f)) == 0) + if ((r = sshkey_format_text(key, entry)) == 0) success = 1; else error_fr(r, "sshkey_write"); - fputc('\n', f); + if ((r = sshbuf_putf(entry, "\n")) != 0) + fatal_fr(r, "sshbuf_putf"); + /* If hashing is enabled, the IP address needs to go on its own line */ if (success && store_hash && ip != NULL) - success = write_host_entry(f, ip, NULL, key, 1); + success = format_host_entry(entry, ip, NULL, key, 1); + return success; +} + +static int +write_host_entry(FILE *f, const char *host, const char *ip, + const struct sshkey *key, int store_hash) +{ + int r, success = 0; + struct sshbuf *entry = NULL; + + if ((entry = sshbuf_new()) == NULL) + fatal_f("allocation failed"); + if ((r = format_host_entry(entry, host, ip, key, store_hash)) != 1) { + debug_f("failed to format host entry"); + goto out; + } + if ((r = fwrite(sshbuf_ptr(entry), sshbuf_len(entry), 1, f)) != 1) { + error_f("fwrite: %s", strerror(errno)); + goto out; + } + success = 1; + out: + sshbuf_free(entry); return success; } @@ -520,9 +548,9 @@ add_host_to_hostfile(const char *filename, const char *host, if (key == NULL) return 1; /* XXX ? */ hostfile_create_user_ssh_dir(filename, 0); - f = fopen(filename, "a+"); - if (!f) + if ((f = fopen(filename, "a+")) == NULL) return 0; + setvbuf(f, NULL, _IONBF, 0); /* Make sure we have a terminating newline. */ if (fseek(f, -1L, SEEK_END) == 0 && fgetc(f) != '\n') addnl = 1; @@ -598,7 +626,7 @@ hostfile_replace_entries(const char *filename, const char *host, const char *ip, int r, fd, oerrno = 0; int loglevel = quiet ? SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_VERBOSE; struct host_delete_ctx ctx; - char *fp, *temp = NULL, *back = NULL; + char *fp = NULL, *temp = NULL, *back = NULL; const char *what; mode_t omask; size_t i; @@ -687,6 +715,7 @@ hostfile_replace_entries(const char *filename, const char *host, const char *ip, host, ip == NULL ? "" : ",", ip == NULL ? "" : ip, filename, sshkey_ssh_name(keys[i]), fp); free(fp); + fp = NULL; ctx.modified = 1; } fclose(ctx.out); @@ -727,6 +756,7 @@ hostfile_replace_entries(const char *filename, const char *host, const char *ip, unlink(temp); free(temp); free(back); + free(fp); if (ctx.out != NULL) fclose(ctx.out); free(ctx.match_keys); @@ -810,6 +840,12 @@ hostkeys_foreach_file(const char *path, FILE *f, hostkeys_foreach_fn *callback, /* Find the end of the host name portion. */ for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++) ; + if (*cp2 == '\0') { + verbose_f("truncated line at %s:%lu", path, linenum); + if ((options & HKF_WANT_MATCH) == 0) + goto bad; + continue; + } lineinfo.hosts = cp; *cp2++ = '\0'; diff --git a/includes.h b/includes.h index 6d17ef6..96cddbc 100644 --- a/includes.h +++ b/includes.h @@ -34,6 +34,9 @@ #ifdef HAVE_ENDIAN_H # include #endif +#ifdef HAVE_FCNTL_H +# include +#endif #ifdef HAVE_TTYENT_H # include #endif @@ -49,6 +52,9 @@ #ifdef HAVE_PATHS_H # include #endif +#ifdef HAVE_FCNTL_H +# include /* For AT_FDCWD */ +#endif /* *-*-nto-qnx needs these headers for strcasecmp and LASTLOG_FILE respectively diff --git a/kex-names.c b/kex-names.c index ec840c1..751f06c 100644 --- a/kex-names.c +++ b/kex-names.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kex-names.c,v 1.4 2024/09/09 02:39:57 djm Exp $ */ +/* $OpenBSD: kex-names.c,v 1.7 2026/02/14 00:18:34 jsg Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * @@ -28,7 +28,6 @@ #include #include #include -#include #include #ifdef WITH_OPENSSL @@ -43,72 +42,63 @@ #include "misc.h" #include "ssherr.h" -#include "xmalloc.h" struct kexalg { char *name; u_int type; int ec_nid; int hash_alg; + int pq_alg; }; static const struct kexalg kexalgs[] = { #ifdef WITH_OPENSSL - { KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 }, - { KEX_DH14_SHA1, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, - { KEX_DH14_SHA256, KEX_DH_GRP14_SHA256, 0, SSH_DIGEST_SHA256 }, - { KEX_DH16_SHA512, KEX_DH_GRP16_SHA512, 0, SSH_DIGEST_SHA512 }, - { KEX_DH18_SHA512, KEX_DH_GRP18_SHA512, 0, SSH_DIGEST_SHA512 }, - { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, + { KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1, KEX_NOT_PQ }, + { KEX_DH14_SHA1, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1, KEX_NOT_PQ }, + { KEX_DH14_SHA256, KEX_DH_GRP14_SHA256, 0, SSH_DIGEST_SHA256, KEX_NOT_PQ }, + { KEX_DH16_SHA512, KEX_DH_GRP16_SHA512, 0, SSH_DIGEST_SHA512, KEX_NOT_PQ }, + { KEX_DH18_SHA512, KEX_DH_GRP18_SHA512, 0, SSH_DIGEST_SHA512, KEX_NOT_PQ }, + { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1, KEX_NOT_PQ }, #ifdef HAVE_EVP_SHA256 - { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 }, + { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256, KEX_NOT_PQ }, #endif /* HAVE_EVP_SHA256 */ #ifdef OPENSSL_HAS_ECC { KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2, - NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, + NID_X9_62_prime256v1, SSH_DIGEST_SHA256, KEX_NOT_PQ }, { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1, - SSH_DIGEST_SHA384 }, + SSH_DIGEST_SHA384, KEX_NOT_PQ }, # ifdef OPENSSL_HAS_NISTP521 { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1, - SSH_DIGEST_SHA512 }, + SSH_DIGEST_SHA512, KEX_NOT_PQ }, # endif /* OPENSSL_HAS_NISTP521 */ #endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ #if defined(HAVE_EVP_SHA256) || !defined(WITH_OPENSSL) - { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, - { KEX_CURVE25519_SHA256_OLD, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, + { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256, KEX_NOT_PQ }, + { KEX_CURVE25519_SHA256_OLD, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256, KEX_NOT_PQ }, #ifdef USE_SNTRUP761X25519 { KEX_SNTRUP761X25519_SHA512, KEX_KEM_SNTRUP761X25519_SHA512, 0, - SSH_DIGEST_SHA512 }, + SSH_DIGEST_SHA512, KEX_IS_PQ }, { KEX_SNTRUP761X25519_SHA512_OLD, KEX_KEM_SNTRUP761X25519_SHA512, 0, - SSH_DIGEST_SHA512 }, + SSH_DIGEST_SHA512, KEX_IS_PQ }, #endif #ifdef USE_MLKEM768X25519 { KEX_MLKEM768X25519_SHA256, KEX_KEM_MLKEM768X25519_SHA256, 0, - SSH_DIGEST_SHA256 }, + SSH_DIGEST_SHA256, KEX_IS_PQ }, #endif #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ - { NULL, 0, -1, -1}, + { NULL, 0, -1, -1, 0 }, }; char * kex_alg_list(char sep) { - char *ret = NULL, *tmp; - size_t nlen, rlen = 0; + char *ret = NULL; const struct kexalg *k; + char sep_str[2] = {sep, '\0'}; + + for (k = kexalgs; k->name != NULL; k++) + xextendf(&ret, sep_str, "%s", k->name); - for (k = kexalgs; k->name != NULL; k++) { - if (ret != NULL) - ret[rlen++] = sep; - nlen = strlen(k->name); - if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) { - free(ret); - return NULL; - } - ret = tmp; - memcpy(ret + rlen, k->name, nlen + 1); - rlen += nlen; - } return ret; } @@ -130,6 +120,16 @@ kex_name_valid(const char *name) return kex_alg_by_name(name) != NULL; } +int +kex_is_pq_from_name(const char *name) +{ + const struct kexalg *k; + + if ((k = kex_alg_by_name(name)) == NULL) + return 0; + return k->pq_alg == KEX_IS_PQ; +} + u_int kex_type_from_name(const char *name) { diff --git a/kex.c b/kex.c index 6b957e5..85b112c 100644 --- a/kex.c +++ b/kex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.c,v 1.187 2024/08/23 04:51:00 deraadt Exp $ */ +/* $OpenBSD: kex.c,v 1.193 2026/03/05 05:40:35 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * @@ -33,9 +33,6 @@ #include #include #include -#ifdef HAVE_POLL_H -#include -#endif #ifdef WITH_OPENSSL #include @@ -56,7 +53,6 @@ #include "match.h" #include "misc.h" #include "dispatch.h" -#include "monitor.h" #include "myproposal.h" #include "ssherr.h" @@ -66,7 +62,7 @@ /* prototype */ static int kex_choose_conf(struct ssh *, uint32_t seq); -static int kex_input_newkeys(int, u_int32_t, struct ssh *); +static int kex_input_newkeys(int, uint32_t, struct ssh *); static const char * const proposal_names[PROPOSAL_MAX] = { "KEX algorithms", @@ -233,7 +229,7 @@ kex_prop_free(char **proposal) } int -kex_protocol_error(int type, u_int32_t seq, struct ssh *ssh) +kex_protocol_error(int type, uint32_t seq, struct ssh *ssh) { int r; @@ -301,13 +297,15 @@ kex_compose_ext_info_server(struct ssh *ssh, struct sshbuf *m) if (ssh->kex->server_sig_algs == NULL && (ssh->kex->server_sig_algs = sshkey_alg_list(0, 1, 1, ',')) == NULL) return SSH_ERR_ALLOC_FAIL; - if ((r = sshbuf_put_u32(m, 3)) != 0 || + if ((r = sshbuf_put_u32(m, 4)) != 0 || (r = sshbuf_put_cstring(m, "server-sig-algs")) != 0 || (r = sshbuf_put_cstring(m, ssh->kex->server_sig_algs)) != 0 || (r = sshbuf_put_cstring(m, "publickey-hostbound@openssh.com")) != 0 || (r = sshbuf_put_cstring(m, "0")) != 0 || (r = sshbuf_put_cstring(m, "ping@openssh.com")) != 0 || + (r = sshbuf_put_cstring(m, "0")) != 0 || + (r = sshbuf_put_cstring(m, "agent-forward")) != 0 || (r = sshbuf_put_cstring(m, "0")) != 0) { error_fr(r, "compose"); return r; @@ -451,6 +449,12 @@ kex_ext_info_client_parse(struct ssh *ssh, const char *name, "0", KEX_HAS_PING)) != 0) { return r; } + } else if (ssh->kex->ext_info_received == 1 && + strcmp(name, "agent-forward") == 0) { + if ((r = kex_ext_info_check_ver(ssh->kex, name, value, vlen, + "0", KEX_HAS_NEWAGENT)) != 0) { + return r; + } } else debug_f("%s (unrecognised)", name); @@ -474,11 +478,11 @@ kex_ext_info_server_parse(struct ssh *ssh, const char *name, } int -kex_input_ext_info(int type, u_int32_t seq, struct ssh *ssh) +kex_input_ext_info(int type, uint32_t seq, struct ssh *ssh) { struct kex *kex = ssh->kex; const int max_ext_info = kex->server ? 1 : 2; - u_int32_t i, ninfo; + uint32_t i, ninfo; char *name; u_char *val; size_t vlen; @@ -521,7 +525,7 @@ kex_input_ext_info(int type, u_int32_t seq, struct ssh *ssh) } static int -kex_input_newkeys(int type, u_int32_t seq, struct ssh *ssh) +kex_input_newkeys(int type, uint32_t seq, struct ssh *ssh) { struct kex *kex = ssh->kex; int r, initial = (kex->flags & KEX_INITIAL) != 0; @@ -563,8 +567,6 @@ kex_input_newkeys(int type, u_int32_t seq, struct ssh *ssh) kex->flags &= ~KEX_INITIAL; sshbuf_reset(kex->peer); kex->flags &= ~KEX_INIT_SENT; - free(kex->name); - kex->name = NULL; return 0; } @@ -607,7 +609,7 @@ kex_send_kexinit(struct ssh *ssh) } int -kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh) +kex_input_kexinit(int type, uint32_t seq, struct ssh *ssh) { struct kex *kex = ssh->kex; const u_char *ptr; @@ -620,6 +622,8 @@ kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh) error_f("no kex"); return SSH_ERR_INTERNAL_ERROR; } + free(kex->name); + kex->name = NULL; ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_protocol_error); ptr = sshpkt_ptr(ssh, &dlen); if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0) @@ -742,6 +746,7 @@ kex_free(struct kex *kex) free(kex->failed_choice); free(kex->hostkey_alg); free(kex->name); + free(kex->server_sig_algs); free(kex); } diff --git a/kex.h b/kex.h index d08988b..4f6d921 100644 --- a/kex.h +++ b/kex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.h,v 1.126 2024/09/02 12:13:56 djm Exp $ */ +/* $OpenBSD: kex.h,v 1.129 2026/03/05 05:40:36 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -114,6 +114,11 @@ enum kex_exchange { #define KEX_RSA_SHA2_512_SUPPORTED 0x0010 /* only set in server for now */ #define KEX_HAS_PING 0x0020 #define KEX_HAS_EXT_INFO_IN_AUTH 0x0040 +#define KEX_HAS_NEWAGENT 0x0080 /* only set in client */ + +/* kex->pq */ +#define KEX_NOT_PQ 0 +#define KEX_IS_PQ 1 struct sshenc { char *name; @@ -189,6 +194,7 @@ int kex_name_valid(const char *); u_int kex_type_from_name(const char *); int kex_hash_from_name(const char *); int kex_nid_from_name(const char *); +int kex_is_pq_from_name(const char *); int kex_names_valid(const char *); char *kex_alg_list(char); char *kex_names_cat(const char *, const char *); @@ -213,9 +219,9 @@ int kex_load_hostkey(struct ssh *, struct sshkey **, struct sshkey **); int kex_verify_host_key(struct ssh *, struct sshkey *); int kex_send_kexinit(struct ssh *); -int kex_input_kexinit(int, u_int32_t, struct ssh *); -int kex_input_ext_info(int, u_int32_t, struct ssh *); -int kex_protocol_error(int, u_int32_t, struct ssh *); +int kex_input_kexinit(int, uint32_t, struct ssh *); +int kex_input_ext_info(int, uint32_t, struct ssh *); +int kex_protocol_error(int, uint32_t, struct ssh *); int kex_derive_keys(struct ssh *, u_char *, u_int, const struct sshbuf *); int kex_send_newkeys(struct ssh *); int kex_start_rekex(struct ssh *); diff --git a/kexdh.c b/kexdh.c index c1084f2..cbcb2d8 100644 --- a/kexdh.c +++ b/kexdh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexdh.c,v 1.34 2020/12/04 02:29:25 djm Exp $ */ +/* $OpenBSD: kexdh.c,v 1.36 2026/02/14 00:18:34 jsg Exp $ */ /* * Copyright (c) 2019 Markus Friedl. All rights reserved. * @@ -26,20 +26,18 @@ #include "includes.h" #ifdef WITH_OPENSSL +#include "openbsd-compat/openssl-compat.h" #include #include -#include #include -#include "openbsd-compat/openssl-compat.h" +#include #include -#include "sshkey.h" #include "kex.h" #include "sshbuf.h" -#include "digest.h" #include "ssherr.h" #include "dh.h" #include "log.h" diff --git a/kexecdh.c b/kexecdh.c index efb2e55..6a9058c 100644 --- a/kexecdh.c +++ b/kexecdh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexecdh.c,v 1.10 2019/01/21 10:40:11 djm Exp $ */ +/* $OpenBSD: kexecdh.c,v 1.12 2026/02/14 00:18:34 jsg Exp $ */ /* * Copyright (c) 2010 Damien Miller. All rights reserved. * Copyright (c) 2019 Markus Friedl. All rights reserved. @@ -31,15 +31,14 @@ #include #include -#include #include +#include #include #include "sshkey.h" #include "kex.h" #include "sshbuf.h" -#include "digest.h" #include "ssherr.h" static int diff --git a/kexgen.c b/kexgen.c index 40d688d..5643bc8 100644 --- a/kexgen.c +++ b/kexgen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexgen.c,v 1.10 2024/09/09 02:39:57 djm Exp $ */ +/* $OpenBSD: kexgen.c,v 1.12 2026/03/03 09:57:25 dtucker Exp $ */ /* * Copyright (c) 2019 Markus Friedl. All rights reserved. * @@ -41,8 +41,8 @@ #include "digest.h" #include "ssherr.h" -static int input_kex_gen_init(int, u_int32_t, struct ssh *); -static int input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh); +static int input_kex_gen_init(int, uint32_t, struct ssh *); +static int input_kex_gen_reply(int type, uint32_t seq, struct ssh *ssh); static int kex_gen_hash( @@ -113,7 +113,7 @@ kex_gen_client(struct ssh *ssh) case KEX_ECDH_SHA2: r = kex_ecdh_keypair(kex); break; -#endif +#endif /* WITH_OPENSSL */ case KEX_C25519_SHA256: r = kex_c25519_keypair(kex); break; @@ -139,7 +139,7 @@ kex_gen_client(struct ssh *ssh) } static int -input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh) +input_kex_gen_reply(int type, uint32_t seq, struct ssh *ssh) { struct kex *kex = ssh->kex; struct sshkey *server_host_key = NULL; @@ -187,7 +187,7 @@ input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh) case KEX_ECDH_SHA2: r = kex_ecdh_dec(kex, server_blob, &shared_secret); break; -#endif +#endif /* WITH_OPENSSL */ case KEX_C25519_SHA256: r = kex_c25519_dec(kex, server_blob, &shared_secret); break; @@ -272,7 +272,7 @@ kex_gen_server(struct ssh *ssh) } static int -input_kex_gen_init(int type, u_int32_t seq, struct ssh *ssh) +input_kex_gen_init(int type, uint32_t seq, struct ssh *ssh) { struct kex *kex = ssh->kex; struct sshkey *server_host_private, *server_host_public; @@ -310,7 +310,7 @@ input_kex_gen_init(int type, u_int32_t seq, struct ssh *ssh) r = kex_ecdh_enc(kex, client_pubkey, &server_pubkey, &shared_secret); break; -#endif +#endif /* WITH_OPENSSL */ case KEX_C25519_SHA256: r = kex_c25519_enc(kex, client_pubkey, &server_pubkey, &shared_secret); diff --git a/kexgex.c b/kexgex.c index 8040a13..daa5a29 100644 --- a/kexgex.c +++ b/kexgex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexgex.c,v 1.32 2019/01/23 00:30:41 djm Exp $ */ +/* $OpenBSD: kexgex.c,v 1.33 2026/02/14 00:18:34 jsg Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved. diff --git a/kexgexc.c b/kexgexc.c index e99e0cf..1c2194a 100644 --- a/kexgexc.c +++ b/kexgexc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexgexc.c,v 1.38 2021/12/19 22:08:06 djm Exp $ */ +/* $OpenBSD: kexgexc.c,v 1.42 2026/03/03 09:57:25 dtucker Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -27,9 +27,11 @@ #include "includes.h" #ifdef WITH_OPENSSL +#include "openbsd-compat/openssl-compat.h" #include +#include #include #include @@ -37,10 +39,7 @@ #include #include -#include "openbsd-compat/openssl-compat.h" - #include "sshkey.h" -#include "cipher.h" #include "digest.h" #include "kex.h" #include "log.h" @@ -53,8 +52,8 @@ #include "sshbuf.h" #include "misc.h" -static int input_kex_dh_gex_group(int, u_int32_t, struct ssh *); -static int input_kex_dh_gex_reply(int, u_int32_t, struct ssh *); +static int input_kex_dh_gex_group(int, uint32_t, struct ssh *); +static int input_kex_dh_gex_reply(int, uint32_t, struct ssh *); int kexgex_client(struct ssh *ssh) @@ -92,7 +91,7 @@ kexgex_client(struct ssh *ssh) } static int -input_kex_dh_gex_group(int type, u_int32_t seq, struct ssh *ssh) +input_kex_dh_gex_group(int type, uint32_t seq, struct ssh *ssh) { struct kex *kex = ssh->kex; BIGNUM *p = NULL, *g = NULL; @@ -142,7 +141,7 @@ input_kex_dh_gex_group(int type, u_int32_t seq, struct ssh *ssh) } static int -input_kex_dh_gex_reply(int type, u_int32_t seq, struct ssh *ssh) +input_kex_dh_gex_reply(int type, uint32_t seq, struct ssh *ssh) { struct kex *kex = ssh->kex; BIGNUM *dh_server_pub = NULL; diff --git a/kexgexs.c b/kexgexs.c index 100be03..791afc2 100644 --- a/kexgexs.c +++ b/kexgexs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexgexs.c,v 1.47 2024/05/17 00:30:23 djm Exp $ */ +/* $OpenBSD: kexgexs.c,v 1.51 2026/03/03 09:57:25 dtucker Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -27,17 +27,16 @@ #include "includes.h" #ifdef WITH_OPENSSL - +#include "openbsd-compat/openssl-compat.h" #include #include #include #include +#include #include -#include "openbsd-compat/openssl-compat.h" - #include "sshkey.h" #include "cipher.h" #include "digest.h" @@ -55,8 +54,8 @@ #include "sshbuf.h" #include "misc.h" -static int input_kex_dh_gex_request(int, u_int32_t, struct ssh *); -static int input_kex_dh_gex_init(int, u_int32_t, struct ssh *); +static int input_kex_dh_gex_request(int, uint32_t, struct ssh *); +static int input_kex_dh_gex_init(int, uint32_t, struct ssh *); int kexgex_server(struct ssh *ssh) @@ -68,7 +67,7 @@ kexgex_server(struct ssh *ssh) } static int -input_kex_dh_gex_request(int type, u_int32_t seq, struct ssh *ssh) +input_kex_dh_gex_request(int type, uint32_t seq, struct ssh *ssh) { struct kex *kex = ssh->kex; int r; @@ -124,7 +123,7 @@ input_kex_dh_gex_request(int type, u_int32_t seq, struct ssh *ssh) } static int -input_kex_dh_gex_init(int type, u_int32_t seq, struct ssh *ssh) +input_kex_dh_gex_init(int type, uint32_t seq, struct ssh *ssh) { struct kex *kex = ssh->kex; BIGNUM *dh_client_pub = NULL; diff --git a/kexmlkem768x25519.c b/kexmlkem768x25519.c index 2b5d396..2585d1d 100644 --- a/kexmlkem768x25519.c +++ b/kexmlkem768x25519.c @@ -28,15 +28,11 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include #include -#ifdef HAVE_ENDIAN_H -# include -#endif +#include #include "sshkey.h" #include "kex.h" diff --git a/krl.c b/krl.c index 0d0f695..0e2b5f1 100644 --- a/krl.c +++ b/krl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: krl.c,v 1.60 2025/02/18 08:02:48 djm Exp $ */ +/* $OpenBSD: krl.c,v 1.64 2026/03/03 09:57:25 dtucker Exp $ */ /* * Copyright (c) 2012 Damien Miller * @@ -18,21 +18,18 @@ #include "includes.h" #include -#include -#include +#include +#include #include -#include #include #include #include #include -#include #include "sshbuf.h" #include "ssherr.h" #include "sshkey.h" -#include "authfile.h" #include "misc.h" #include "log.h" #include "digest.h" @@ -55,7 +52,7 @@ /* Tree of serial numbers. XXX make smarter: really need a real sparse bitmap */ struct revoked_serial { - u_int64_t lo, hi; + uint64_t lo, hi; RB_ENTRY(revoked_serial) tree_entry; }; static int serial_cmp(struct revoked_serial *a, struct revoked_serial *b); @@ -91,9 +88,9 @@ struct revoked_certs { TAILQ_HEAD(revoked_certs_list, revoked_certs); struct ssh_krl { - u_int64_t krl_version; - u_int64_t generated_date; - u_int64_t flags; + uint64_t krl_version; + uint64_t generated_date; + uint64_t flags; char *comment; struct revoked_blob_tree revoked_keys; struct revoked_blob_tree revoked_sha1s; @@ -149,6 +146,8 @@ revoked_certs_free(struct revoked_certs *rc) struct revoked_serial *rs, *trs; struct revoked_key_id *rki, *trki; + if (rc == NULL) + return; RB_FOREACH_SAFE(rs, revoked_serial_tree, &rc->revoked_serials, trs) { RB_REMOVE(revoked_serial_tree, &rc->revoked_serials, rs); free(rs); @@ -159,6 +158,7 @@ revoked_certs_free(struct revoked_certs *rc) free(rki); } sshkey_free(rc->ca_key); + freezero(rc, sizeof(*rc)); } void @@ -194,7 +194,7 @@ ssh_krl_free(struct ssh_krl *krl) } void -ssh_krl_set_version(struct ssh_krl *krl, u_int64_t version) +ssh_krl_set_version(struct ssh_krl *krl, uint64_t version) { krl->krl_version = version; } @@ -247,7 +247,7 @@ revoked_certs_for_ca_key(struct ssh_krl *krl, const struct sshkey *ca_key, } static int -insert_serial_range(struct revoked_serial_tree *rt, u_int64_t lo, u_int64_t hi) +insert_serial_range(struct revoked_serial_tree *rt, uint64_t lo, uint64_t hi) { struct revoked_serial rs, *ers, *crs, *irs; @@ -302,7 +302,7 @@ insert_serial_range(struct revoked_serial_tree *rt, u_int64_t lo, u_int64_t hi) /* Check successors */ while ((crs = RB_NEXT(revoked_serial_tree, rt, ers)) != NULL) { KRL_DBG(("succ %llu:%llu", crs->lo, crs->hi)); - if (ers->hi != (u_int64_t)-1 && crs->lo > ers->hi + 1) + if (ers->hi != (uint64_t)-1 && crs->lo > ers->hi + 1) break; /* This entry overlaps. */ if (crs->hi > ers->hi) { @@ -318,14 +318,14 @@ insert_serial_range(struct revoked_serial_tree *rt, u_int64_t lo, u_int64_t hi) int ssh_krl_revoke_cert_by_serial(struct ssh_krl *krl, const struct sshkey *ca_key, - u_int64_t serial) + uint64_t serial) { return ssh_krl_revoke_cert_by_serial_range(krl, ca_key, serial, serial); } int ssh_krl_revoke_cert_by_serial_range(struct ssh_krl *krl, - const struct sshkey *ca_key, u_int64_t lo, u_int64_t hi) + const struct sshkey *ca_key, uint64_t lo, uint64_t hi) { struct revoked_certs *rc; int r; @@ -474,11 +474,11 @@ ssh_krl_revoke_key(struct ssh_krl *krl, const struct sshkey *key) * that will minimise the size of the resultant KRL. */ static int -choose_next_state(int current_state, u_int64_t contig, int final, - u_int64_t last_gap, u_int64_t next_gap, int *force_new_section) +choose_next_state(int current_state, uint64_t contig, int final, + uint64_t last_gap, uint64_t next_gap, int *force_new_section) { int new_state; - u_int64_t cost, cost_list, cost_range, cost_bitmap, cost_bitmap_restart; + uint64_t cost, cost_list, cost_range, cost_bitmap, cost_bitmap_restart; /* * Avoid unsigned overflows. @@ -573,7 +573,7 @@ static int revoked_certs_generate(struct revoked_certs *rc, struct sshbuf *buf) { int final, force_new_sect, r = SSH_ERR_INTERNAL_ERROR; - u_int64_t i, contig, gap, last = 0, bitmap_start = 0; + uint64_t i, contig, gap, last = 0, bitmap_start = 0; struct revoked_serial *rs, *nrs; struct revoked_key_id *rki; int next_state, state = 0; @@ -808,7 +808,7 @@ ssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf) } static void -format_timestamp(u_int64_t timestamp, char *ts, size_t nts) +format_timestamp(uint64_t timestamp, char *ts, size_t nts) { time_t t; struct tm *tm; @@ -870,7 +870,7 @@ parse_revoked_certs(struct sshbuf *buf, struct ssh_krl *krl) const u_char *blob; size_t blen, nbits; struct sshbuf *subsect = NULL; - u_int64_t serial, serial_lo, serial_hi; + uint64_t serial, serial_lo, serial_hi; struct bitmap *bitmap = NULL; char *key_id = NULL; struct sshkey *ca_key = NULL; @@ -926,7 +926,7 @@ parse_revoked_certs(struct sshbuf *buf, struct ssh_krl *krl) goto out; } nbits = bitmap_nbits(bitmap); - for (serial = 0; serial < (u_int64_t)nbits; serial++) { + for (serial = 0; serial < (uint64_t)nbits; serial++) { if (serial > 0 && serial_lo + serial == 0) { error_f("bitmap wraps u64"); r = SSH_ERR_INVALID_FORMAT; diff --git a/krl.h b/krl.h index eb24476..5e10167 100644 --- a/krl.h +++ b/krl.h @@ -14,7 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $OpenBSD: krl.h,v 1.10 2023/07/17 04:01:10 djm Exp $ */ +/* $OpenBSD: krl.h,v 1.11 2026/03/03 09:57:25 dtucker Exp $ */ #ifndef _KRL_H #define _KRL_H @@ -45,12 +45,12 @@ struct ssh_krl; struct ssh_krl *ssh_krl_init(void); void ssh_krl_free(struct ssh_krl *krl); -void ssh_krl_set_version(struct ssh_krl *krl, u_int64_t version); +void ssh_krl_set_version(struct ssh_krl *krl, uint64_t version); int ssh_krl_set_comment(struct ssh_krl *krl, const char *comment); int ssh_krl_revoke_cert_by_serial(struct ssh_krl *krl, - const struct sshkey *ca_key, u_int64_t serial); + const struct sshkey *ca_key, uint64_t serial); int ssh_krl_revoke_cert_by_serial_range(struct ssh_krl *krl, - const struct sshkey *ca_key, u_int64_t lo, u_int64_t hi); + const struct sshkey *ca_key, uint64_t lo, uint64_t hi); int ssh_krl_revoke_cert_by_key_id(struct ssh_krl *krl, const struct sshkey *ca_key, const char *key_id); int ssh_krl_revoke_key_explicit(struct ssh_krl *krl, const struct sshkey *key); diff --git a/libcrux_mlkem768_sha3.h b/libcrux_mlkem768_sha3.h index b8ac143..1e3dc45 100644 --- a/libcrux_mlkem768_sha3.h +++ b/libcrux_mlkem768_sha3.h @@ -1,6 +1,6 @@ -/* $OpenBSD: libcrux_mlkem768_sha3.h,v 1.2 2024/10/27 02:06:01 djm Exp $ */ +/* $OpenBSD: libcrux_mlkem768_sha3.h,v 1.4 2025/11/13 05:13:06 djm Exp $ */ -/* Extracted from libcrux revision 84c5d87b3092c59294345aa269ceefe0eb97cc35 */ +/* Extracted from libcrux revision 026a87ab6d88ad3626b9fbbf3710d1e0483c1849 */ /* * MIT License @@ -34,100 +34,234 @@ #define KRML_HOST_EPRINTF(...) #define KRML_HOST_EXIT(x) fatal_f("internal error") -/* from libcrux/libcrux-ml-kem/cg/eurydice_glue.h */ -/* - * SPDX-FileCopyrightText: 2024 Eurydice Contributors - * SPDX-FileCopyrightText: 2024 Cryspen Sarl - * - * SPDX-License-Identifier: MIT or Apache-2.0 - */ +static inline void +store64_le(uint8_t dst[8], uint64_t src) +{ + dst[0] = src & 0xff; + dst[1] = (src >> 8) & 0xff; + dst[2] = (src >> 16) & 0xff; + dst[3] = (src >> 24) & 0xff; + dst[4] = (src >> 32) & 0xff; + dst[5] = (src >> 40) & 0xff; + dst[6] = (src >> 48) & 0xff; + dst[7] = (src >> 56) & 0xff; +} -#pragma once +static inline void +store32_le(uint8_t dst[4], uint32_t src) +{ + dst[0] = src & 0xff; + dst[1] = (src >> 8) & 0xff; + dst[2] = (src >> 16) & 0xff; + dst[3] = (src >> 24) & 0xff; +} -#if defined(__cplusplus) -extern "C" { +static inline void +store32_be(uint8_t dst[4], uint32_t src) +{ + dst[0] = (src >> 24) & 0xff; + dst[1] = (src >> 16) & 0xff; + dst[2] = (src >> 8) & 0xff; + dst[3] = src & 0xff; +} + +static inline uint64_t +load64_le(uint8_t src[8]) +{ + return (uint64_t)(src[0]) | + ((uint64_t)(src[1]) << 8) | + ((uint64_t)(src[2]) << 16) | + ((uint64_t)(src[3]) << 24) | + ((uint64_t)(src[4]) << 32) | + ((uint64_t)(src[5]) << 40) | + ((uint64_t)(src[6]) << 48) | + ((uint64_t)(src[7]) << 56); +} + +static inline uint32_t +load32_le(uint8_t src[4]) +{ + return (uint32_t)(src[0]) | + ((uint32_t)(src[1]) << 8) | + ((uint32_t)(src[2]) << 16) | + ((uint32_t)(src[3]) << 24); +} + +#ifdef MISSING_BUILTIN_POPCOUNT +static inline unsigned int +__builtin_popcount(unsigned int num) +{ + const int v[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; + return v[num & 0xf] + v[(num >> 4) & 0xf]; +} #endif +/* from libcrux/libcrux-ml-kem/extracts/c_header_only/generated/eurydice_glue.h */ +#pragma once -// SLICES, ARRAYS, ETC. +#ifdef _MSC_VER +// For __popcnt +#endif + + +// C++ HELPERS -// The MSVC C++ compiler does not support compound literals. -// This CLITERAL is used to turn `(type){...}` into `type{...}` when using a C++ -// compiler. #if defined(__cplusplus) -#define CLITERAL(type) type + +#ifndef KRML_HOST_EPRINTF +#define KRML_HOST_EPRINTF(...) fprintf(stderr, __VA_ARGS__) +#endif + + +#ifndef __cpp_lib_type_identity +template +struct type_identity { + using type = T; +}; + +template +using type_identity_t = typename type_identity::type; #else -#define CLITERAL(type) (type) +using std::type_identity_t; #endif +#define KRML_UNION_CONSTRUCTOR(T) \ + template \ + constexpr T(int t, V U::*m, type_identity_t v) : tag(t) { \ + val.*m = std::move(v); \ + } \ + T() = default; + +#endif + +// GENERAL-PURPOSE STUFF + +#define LowStar_Ignore_ignore(e, t, _ret_t) ((void)e) + +#define EURYDICE_ASSERT(test, msg) \ + do { \ + if (!(test)) { \ + fprintf(stderr, "assertion \"%s\" failed: file \"%s\", line %d\n", msg, \ + __FILE__, __LINE__); \ + exit(255); \ + } \ + } while (0) + +// SLICES, ARRAYS, ETC. + // We represent a slice as a pair of an (untyped) pointer, along with the length // of the slice, i.e. the number of elements in the slice (this is NOT the // number of bytes). This design choice has two important consequences. // - if you need to use `ptr`, you MUST cast it to a proper type *before* -// performing pointer -// arithmetic on it (remember that C desugars pointer arithmetic based on the -// type of the address) +// performing pointer arithmetic on it (remember that C desugars pointer +// arithmetic based on the type of the address) // - if you need to use `len` for a C style function (e.g. memcpy, memcmp), you -// need to multiply it -// by sizeof t, where t is the type of the elements. +// need to multiply it by sizeof t, where t is the type of the elements. // -// Empty slices have `len == 0` and `ptr` always needs to be valid pointer that -// is not NULL (otherwise the construction in EURYDICE_SLICE computes `NULL + -// start`). +// Empty slices have `len == 0` and `ptr` always needs to be a valid pointer +// that is not NULL (otherwise the construction in EURYDICE_SLICE computes `NULL +// + start`). typedef struct { void *ptr; size_t len; } Eurydice_slice; +#if defined(__cplusplus) +#define KRML_CLITERAL(type) type +#else +#define KRML_CLITERAL(type) (type) +#endif + +#if defined(__cplusplus) && defined(__cpp_designated_initializers) || \ + !(defined(__cplusplus)) +#define EURYDICE_CFIELD(X) X +#else +#define EURYDICE_CFIELD(X) +#endif + // Helper macro to create a slice out of a pointer x, a start index in x // (included), and an end index in x (excluded). The argument x must be suitably // cast to something that can decay (see remark above about how pointer // arithmetic works in C), meaning either pointer or array type. #define EURYDICE_SLICE(x, start, end) \ - (CLITERAL(Eurydice_slice){.ptr = (void *)(x + start), .len = end - start}) -#define EURYDICE_SLICE_LEN(s, _) s.len + (KRML_CLITERAL(Eurydice_slice){(void *)(x + start), end - start}) + +// Slice length +#define EURYDICE_SLICE_LEN(s, _) (s).len +#define Eurydice_slice_len(s, _) (s).len + // This macro is a pain because in case the dereferenced element type is an // array, you cannot simply write `t x` as it would yield `int[4] x` instead, // which is NOT correct C syntax, so we add a dedicated phase in Eurydice that // adds an extra argument to this macro at the last minute so that we have the // correct type of *pointers* to elements. #define Eurydice_slice_index(s, i, t, t_ptr_t) (((t_ptr_t)s.ptr)[i]) -#define Eurydice_slice_subslice(s, r, t, _) \ + +// The following functions get sub slices from a slice. + +#define Eurydice_slice_subslice(s, r, t, _0, _1) \ EURYDICE_SLICE((t *)s.ptr, r.start, r.end) + // Variant for when the start and end indices are statically known (i.e., the // range argument `r` is a literal). #define Eurydice_slice_subslice2(s, start, end, t) \ - EURYDICE_SLICE((t *)s.ptr, start, end) -#define Eurydice_slice_subslice_to(s, subslice_end_pos, t, _) \ + EURYDICE_SLICE((t *)s.ptr, (start), (end)) + +// Previous version above does not work when t is an array type (as usual). Will +// be deprecated soon. +#define Eurydice_slice_subslice3(s, start, end, t_ptr) \ + EURYDICE_SLICE((t_ptr)s.ptr, (start), (end)) + +#define Eurydice_slice_subslice_to(s, subslice_end_pos, t, _0, _1) \ EURYDICE_SLICE((t *)s.ptr, 0, subslice_end_pos) -#define Eurydice_slice_subslice_from(s, subslice_start_pos, t, _) \ + +#define Eurydice_slice_subslice_from(s, subslice_start_pos, t, _0, _1) \ EURYDICE_SLICE((t *)s.ptr, subslice_start_pos, s.len) + #define Eurydice_array_to_slice(end, x, t) \ EURYDICE_SLICE(x, 0, \ end) /* x is already at an array type, no need for cast */ -#define Eurydice_array_to_subslice(_arraylen, x, r, t, _) \ +#define Eurydice_array_to_subslice(_arraylen, x, r, t, _0, _1) \ EURYDICE_SLICE((t *)x, r.start, r.end) + // Same as above, variant for when start and end are statically known #define Eurydice_array_to_subslice2(x, start, end, t) \ - EURYDICE_SLICE((t *)x, start, end) -#define Eurydice_array_to_subslice_to(_size, x, r, t, _range_t) \ + EURYDICE_SLICE((t *)x, (start), (end)) + +// Same as above, variant for when start and end are statically known +#define Eurydice_array_to_subslice3(x, start, end, t_ptr) \ + EURYDICE_SLICE((t_ptr)x, (start), (end)) + +#define Eurydice_array_repeat(dst, len, init, t) \ + ERROR "should've been desugared" + +// The following functions convert an array into a slice. + +#define Eurydice_array_to_subslice_to(_size, x, r, t, _range_t, _0) \ EURYDICE_SLICE((t *)x, 0, r) -#define Eurydice_array_to_subslice_from(size, x, r, t, _range_t) \ +#define Eurydice_array_to_subslice_from(size, x, r, t, _range_t, _0) \ EURYDICE_SLICE((t *)x, r, size) -#define Eurydice_slice_len(s, t) EURYDICE_SLICE_LEN(s, t) + +// Copy a slice with memcopy #define Eurydice_slice_copy(dst, src, t) \ memcpy(dst.ptr, src.ptr, dst.len * sizeof(t)) -#define core_array___Array_T__N__23__as_slice(len_, ptr_, t, _ret_t) \ - ((Eurydice_slice){.ptr = ptr_, .len = len_}) -#define core_array___core__clone__Clone_for__Array_T__N___20__clone( \ - len, src, dst, elem_type, _ret_t) \ +#define core_array___Array_T__N___as_slice(len_, ptr_, t, _ret_t) \ + KRML_CLITERAL(Eurydice_slice) { ptr_, len_ } + +#define core_array__core__clone__Clone_for__Array_T__N___clone( \ + len, src, dst, elem_type, _ret_t) \ (memcpy(dst, src, len * sizeof(elem_type))) #define TryFromSliceError uint8_t +#define core_array_TryFromSliceError uint8_t + +#define Eurydice_array_eq(sz, a1, a2, t) (memcmp(a1, a2, sz * sizeof(t)) == 0) + +// core::cmp::PartialEq<&0 (@Slice)> for @Array +#define Eurydice_array_eq_slice(sz, a1, s2, t, _) \ + (memcmp(a1, (s2)->ptr, sz * sizeof(t)) == 0) -#define Eurydice_array_eq(sz, a1, a2, t, _) \ - (memcmp(a1, a2, sz * sizeof(t)) == 0) #define core_array_equality___core__cmp__PartialEq__Array_U__N___for__Array_T__N____eq( \ sz, a1, a2, t, _, _ret_t) \ Eurydice_array_eq(sz, a1, a2, t, _) @@ -135,20 +269,30 @@ typedef struct { sz, a1, a2, t, _, _ret_t) \ Eurydice_array_eq(sz, a1, ((a2)->ptr), t, _) -#define Eurydice_slice_split_at(slice, mid, element_type, ret_t) \ - (CLITERAL(ret_t){ \ - .fst = EURYDICE_SLICE((element_type *)slice.ptr, 0, mid), \ - .snd = EURYDICE_SLICE((element_type *)slice.ptr, mid, slice.len)}) -#define Eurydice_slice_split_at_mut(slice, mid, element_type, ret_t) \ - (CLITERAL(ret_t){ \ - .fst = {.ptr = slice.ptr, .len = mid}, \ - .snd = {.ptr = (char *)slice.ptr + mid * sizeof(element_type), \ - .len = slice.len - mid}}) +#define Eurydice_slice_split_at(slice, mid, element_type, ret_t) \ + KRML_CLITERAL(ret_t) { \ + EURYDICE_CFIELD(.fst =) \ + EURYDICE_SLICE((element_type *)(slice).ptr, 0, mid), \ + EURYDICE_CFIELD(.snd =) \ + EURYDICE_SLICE((element_type *)(slice).ptr, mid, (slice).len) \ + } + +#define Eurydice_slice_split_at_mut(slice, mid, element_type, ret_t) \ + KRML_CLITERAL(ret_t) { \ + EURYDICE_CFIELD(.fst =) \ + KRML_CLITERAL(Eurydice_slice){EURYDICE_CFIELD(.ptr =)(slice.ptr), \ + EURYDICE_CFIELD(.len =) mid}, \ + EURYDICE_CFIELD(.snd =) KRML_CLITERAL(Eurydice_slice) { \ + EURYDICE_CFIELD(.ptr =) \ + ((char *)slice.ptr + mid * sizeof(element_type)), \ + EURYDICE_CFIELD(.len =)(slice.len - mid) \ + } \ + } // Conversion of slice to an array, rewritten (by Eurydice) to name the // destination array, since arrays are not values in C. // N.B.: see note in karamel/lib/Inlining.ml if you change this. -#define Eurydice_slice_to_array2(dst, src, _, t_arr) \ +#define Eurydice_slice_to_array2(dst, src, _0, t_arr, _1) \ Eurydice_slice_to_array3(&(dst)->tag, (char *)&(dst)->val.case_Ok, src, \ sizeof(t_arr)) @@ -158,25 +302,96 @@ static inline void Eurydice_slice_to_array3(uint8_t *dst_tag, char *dst_ok, memcpy(dst_ok, src.ptr, sz); } +// SUPPORT FOR DSTs (Dynamically-Sized Types) + +// A DST is a fat pointer that keeps tracks of the size of it flexible array +// member. Slices are a specific case of DSTs, where [T; N] implements +// Unsize<[T]>, meaning an array of statically known size can be converted to a +// fat pointer, i.e. a slice. +// +// Unlike slices, DSTs have a built-in definition that gets monomorphized, of +// the form: +// +// typedef struct { +// T *ptr; +// size_t len; // number of elements +// } Eurydice_dst; +// +// Furthermore, T = T0<[U0]> where `struct T0`, where the `U` is the +// last field. This means that there are two monomorphizations of T0 in the +// program. One is `T0<[V; N]>` +// -- this is directly converted to a Eurydice_dst via suitable codegen (no +// macro). The other is `T = T0<[U]>`, where `[U]` gets emitted to +// `Eurydice_derefed_slice`, a type that only appears in that precise situation +// and is thus defined to give rise to a flexible array member. + +typedef char Eurydice_derefed_slice[]; + +#define Eurydice_slice_of_dst(fam_ptr, len_, t, _) \ + ((Eurydice_slice){.ptr = (void *)(fam_ptr), .len = len_}) + +#define Eurydice_slice_of_boxed_array(ptr_, len_, t, _) \ + ((Eurydice_slice){.ptr = (void *)(ptr_), .len = len_}) + // CORE STUFF (conversions, endianness, ...) -static inline void core_num__u64_9__to_le_bytes(uint64_t v, uint8_t buf[8]) { - v = htole64(v); - memcpy(buf, &v, sizeof(v)); +// We slap extern "C" on declarations that intend to implement a prototype +// generated by Eurydice, because Eurydice prototypes are always emitted within +// an extern "C" block, UNLESS you use -fcxx17-compat, in which case, you must +// pass -DKRML_CXX17_COMPAT="" to your C++ compiler. +#if defined(__cplusplus) && !defined(KRML_CXX17_COMPAT) +extern "C" { +#endif + +static inline void core_num__u32__to_be_bytes(uint32_t src, uint8_t dst[4]) { + store32_be(dst, src); +} + +static inline void core_num__u32__to_le_bytes(uint32_t src, uint8_t dst[4]) { + store32_le(dst, src); +} + +static inline uint32_t core_num__u32__from_le_bytes(uint8_t buf[4]) { + return load32_le(buf); +} + +static inline void core_num__u64__to_le_bytes(uint64_t v, uint8_t buf[8]) { + store64_le(buf, v); +} + +static inline uint64_t core_num__u64__from_le_bytes(uint8_t buf[8]) { + return load64_le(buf); } -static inline uint64_t core_num__u64_9__from_le_bytes(uint8_t buf[8]) { - uint64_t v; - memcpy(&v, buf, sizeof(v)); - return le64toh(v); + +static inline int64_t core_convert_num___core__convert__From_i32__for_i64__from( + int32_t x) { + return x; +} + +static inline uint64_t core_convert_num___core__convert__From_u8__for_u64__from( + uint8_t x) { + return x; +} + +static inline uint64_t +core_convert_num___core__convert__From_u16__for_u64__from(uint16_t x) { + return x; +} + +static inline size_t +core_convert_num___core__convert__From_u16__for_usize__from(uint16_t x) { + return x; } -static inline uint32_t core_num__u32_8__from_le_bytes(uint8_t buf[4]) { - uint32_t v; - memcpy(&v, buf, sizeof(v)); - return le32toh(v); +static inline uint32_t core_num__u8__count_ones(uint8_t x0) { +#ifdef _MSC_VER + return __popcnt(x0); +#else + return __builtin_popcount(x0); +#endif } -static inline uint32_t core_num__u8_6__count_ones(uint8_t x0) { +static inline uint32_t core_num__i32__count_ones(int32_t x0) { #ifdef _MSC_VER return __popcnt(x0); #else @@ -184,96 +399,212 @@ static inline uint32_t core_num__u8_6__count_ones(uint8_t x0) { #endif } +static inline size_t core_cmp_impls___core__cmp__Ord_for_usize__min(size_t a, + size_t b) { + if (a <= b) + return a; + else + return b; +} + // unsigned overflow wraparound semantics in C -static inline uint16_t core_num__u16_7__wrapping_add(uint16_t x, uint16_t y) { +static inline uint16_t core_num__u16__wrapping_add(uint16_t x, uint16_t y) { return x + y; } -static inline uint8_t core_num__u8_6__wrapping_sub(uint8_t x, uint8_t y) { +static inline uint8_t core_num__u8__wrapping_sub(uint8_t x, uint8_t y) { return x - y; } +static inline uint64_t core_num__u64__rotate_left(uint64_t x0, uint32_t x1) { + return (x0 << x1 | x0 >> (64 - x1)); +} + +static inline void core_ops_arith__i32__add_assign(int32_t *x0, int32_t *x1) { + *x0 = *x0 + *x1; +} + +static inline uint8_t Eurydice_bitand_pv_u8(uint8_t *p, uint8_t v) { + return (*p) & v; +} +static inline uint8_t Eurydice_shr_pv_u8(uint8_t *p, int32_t v) { + return (*p) >> v; +} +static inline uint32_t Eurydice_min_u32(uint32_t x, uint32_t y) { + return x < y ? x : y; +} + +static inline uint8_t +core_ops_bit___core__ops__bit__BitAnd_u8__u8__for___a__u8___46__bitand( + uint8_t *x0, uint8_t x1) { + return Eurydice_bitand_pv_u8(x0, x1); +} + +static inline uint8_t +core_ops_bit___core__ops__bit__Shr_i32__u8__for___a__u8___792__shr(uint8_t *x0, + int32_t x1) { + return Eurydice_shr_pv_u8(x0, x1); +} + +#define core_num_nonzero_private_NonZeroUsizeInner size_t +static inline core_num_nonzero_private_NonZeroUsizeInner +core_num_nonzero_private___core__clone__Clone_for_core__num__nonzero__private__NonZeroUsizeInner__26__clone( + core_num_nonzero_private_NonZeroUsizeInner *x0) { + return *x0; +} + +#if defined(__cplusplus) && !defined(KRML_CXX17_COMPAT) +} +#endif // ITERATORS -#define Eurydice_range_iter_next(iter_ptr, t, ret_t) \ - (((iter_ptr)->start == (iter_ptr)->end) \ - ? (CLITERAL(ret_t){.tag = None}) \ - : (CLITERAL(ret_t){.tag = Some, .f0 = (iter_ptr)->start++})) +#define Eurydice_range_iter_next(iter_ptr, t, ret_t) \ + (((iter_ptr)->start >= (iter_ptr)->end) \ + ? (KRML_CLITERAL(ret_t){EURYDICE_CFIELD(.tag =) 0, \ + EURYDICE_CFIELD(.f0 =) 0}) \ + : (KRML_CLITERAL(ret_t){EURYDICE_CFIELD(.tag =) 1, \ + EURYDICE_CFIELD(.f0 =)(iter_ptr)->start++})) -#define core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next \ +#define core_iter_range___core__iter__traits__iterator__Iterator_A__for_core__ops__range__Range_A__TraitClause_0___6__next \ Eurydice_range_iter_next // See note in karamel/lib/Inlining.ml if you change this -#define Eurydice_into_iter(x, t, _ret_t) (x) -#define core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter \ +#define Eurydice_into_iter(x, t, _ret_t, _) (x) +#define core_iter_traits_collect___core__iter__traits__collect__IntoIterator_Clause1_Item__I__for_I__1__into_iter \ Eurydice_into_iter -#if defined(__cplusplus) -} -#endif +typedef struct { + Eurydice_slice slice; + size_t chunk_size; +} Eurydice_chunks; + +// Can't use macros Eurydice_slice_subslice_{to,from} because they require a +// type, and this static inline function cannot receive a type as an argument. +// Instead, we receive the element size and use it to peform manual offset +// computations rather than going through the macros. +static inline Eurydice_slice chunk_next(Eurydice_chunks *chunks, + size_t element_size) { + size_t chunk_size = chunks->slice.len >= chunks->chunk_size + ? chunks->chunk_size + : chunks->slice.len; + Eurydice_slice curr_chunk; + curr_chunk.ptr = chunks->slice.ptr; + curr_chunk.len = chunk_size; + chunks->slice.ptr = (char *)(chunks->slice.ptr) + chunk_size * element_size; + chunks->slice.len = chunks->slice.len - chunk_size; + return curr_chunk; +} + +#define core_slice___Slice_T___chunks(slice_, sz_, t, _ret_t) \ + ((Eurydice_chunks){.slice = slice_, .chunk_size = sz_}) +#define core_slice___Slice_T___chunks_exact(slice_, sz_, t, _ret_t) \ + ((Eurydice_chunks){ \ + .slice = {.ptr = slice_.ptr, .len = slice_.len - (slice_.len % sz_)}, \ + .chunk_size = sz_}) +#define core_slice_iter_Chunks Eurydice_chunks +#define core_slice_iter_ChunksExact Eurydice_chunks +#define Eurydice_chunks_next(iter, t, ret_t) \ + (((iter)->slice.len == 0) ? ((ret_t){.tag = core_option_None}) \ + : ((ret_t){.tag = core_option_Some, \ + .f0 = chunk_next(iter, sizeof(t))})) +#define core_slice_iter___core__iter__traits__iterator__Iterator_for_core__slice__iter__Chunks__a__T___70__next \ + Eurydice_chunks_next +// This name changed on 20240627 +#define core_slice_iter___core__iter__traits__iterator__Iterator_for_core__slice__iter__Chunks__a__T___71__next \ + Eurydice_chunks_next +#define core_slice_iter__core__slice__iter__ChunksExact__a__T__89__next( \ + iter, t, _ret_t) \ + core_slice_iter__core__slice__iter__Chunks__a__T__70__next(iter, t) -/* from libcrux/libcrux-ml-kem/cg/libcrux_core.h */ +typedef struct { + Eurydice_slice s; + size_t index; +} Eurydice_slice_iterator; + +#define core_slice___Slice_T___iter(x, t, _ret_t) \ + ((Eurydice_slice_iterator){.s = x, .index = 0}) +#define core_slice_iter_Iter Eurydice_slice_iterator +#define core_slice_iter__core__slice__iter__Iter__a__T__181__next(iter, t, \ + ret_t) \ + (((iter)->index == (iter)->s.len) \ + ? (KRML_CLITERAL(ret_t){.tag = core_option_None}) \ + : (KRML_CLITERAL(ret_t){ \ + .tag = core_option_Some, \ + .f0 = ((iter)->index++, \ + &((t *)((iter)->s.ptr))[(iter)->index - 1])})) +#define core_option__core__option__Option_T__TraitClause_0___is_some(X, _0, \ + _1) \ + ((X)->tag == 1) +// STRINGS + +typedef const char *Prims_string; + +// MISC (UNTESTED) + +typedef void *core_fmt_Formatter; +typedef void *core_fmt_Arguments; +typedef void *core_fmt_rt_Argument; +#define core_fmt_rt__core__fmt__rt__Argument__a__1__new_display(x1, x2, x3, \ + x4) \ + NULL + +// BOXES + +// Crimes. +static inline char *malloc_and_init(size_t sz, char *init) { + char *ptr = (char *)malloc(sz); + memcpy(ptr, init, sz); + return ptr; +} + +#define Eurydice_box_new(init, t, t_dst) \ + ((t_dst)(malloc_and_init(sizeof(t), (char *)(&init)))) + +#define Eurydice_box_new_array(len, ptr, t, t_dst) \ + ((t_dst)(malloc_and_init(len * sizeof(t), (char *)(ptr)))) + +/* from libcrux/libcrux-ml-kem/extracts/c_header_only/generated/libcrux_mlkem_core.h */ /* - * SPDX-FileCopyrightText: 2024 Cryspen Sarl + * SPDX-FileCopyrightText: 2025 Cryspen Sarl * * SPDX-License-Identifier: MIT or Apache-2.0 * * This code was generated with the following revisions: - * Charon: 6b5e110342a771a3e1c739b10294b1778e4be8b4 - * Eurydice: 31be7d65ca5d6acdacfb33652e478d24dd85c1cb - * Karamel: 3205d3365ea2790b02368f79fcee38e38d0b5908 - * F*: a32b316e521fa4f239b610ec8f1d15e78d62cbe8-dirty - * Libcrux: 4ad532b206174114dd4140b718e7794a28fc59ee + * Charon: 667d2fc98984ff7f3df989c2367e6c1fa4a000e7 + * Eurydice: 2381cbc416ef2ad0b561c362c500bc84f36b6785 + * Karamel: 80f5435f2fc505973c469a4afcc8d875cddd0d8b + * F*: 71d8221589d4d438af3706d89cb653cf53e18aab + * Libcrux: 68dfed5a4a9e40277f62828471c029afed1ecdcc */ -#ifndef __libcrux_core_H -#define __libcrux_core_H +#ifndef libcrux_mlkem_core_H +#define libcrux_mlkem_core_H + #if defined(__cplusplus) extern "C" { #endif - /** A monomorphic instance of core.ops.range.Range with types size_t */ -typedef struct core_ops_range_Range_b3_s { +typedef struct core_ops_range_Range_08_s { size_t start; size_t end; -} core_ops_range_Range_b3; - -#define Ok 0 -#define Err 1 - -typedef uint8_t Result_86_tags; - -#define None 0 -#define Some 1 - -typedef uint8_t Option_ef_tags; - -/** -A monomorphic instance of core.option.Option -with types size_t +} core_ops_range_Range_08; -*/ -typedef struct Option_b3_s { - Option_ef_tags tag; - size_t f0; -} Option_b3; - -static inline uint16_t core_num__u16_7__wrapping_add(uint16_t x0, uint16_t x1); +static inline uint16_t core_num__u16__wrapping_add(uint16_t x0, uint16_t x1); -#define CORE_NUM__U32_8__BITS (32U) +static inline uint64_t core_num__u64__from_le_bytes(uint8_t x0[8U]); -static inline uint64_t core_num__u64_9__from_le_bytes(uint8_t x0[8U]); +static inline uint64_t core_num__u64__rotate_left(uint64_t x0, uint32_t x1); -static inline void core_num__u64_9__to_le_bytes(uint64_t x0, uint8_t x1[8U]); +static inline void core_num__u64__to_le_bytes(uint64_t x0, uint8_t x1[8U]); -static inline uint32_t core_num__u8_6__count_ones(uint8_t x0); +static inline uint32_t core_num__u8__count_ones(uint8_t x0); -static inline uint8_t core_num__u8_6__wrapping_sub(uint8_t x0, uint8_t x1); +static inline uint8_t core_num__u8__wrapping_sub(uint8_t x0, uint8_t x1); #define LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE ((size_t)32U) @@ -289,240 +620,478 @@ static inline uint8_t core_num__u8_6__wrapping_sub(uint8_t x0, uint8_t x1); #define LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE ((size_t)32U) -#define LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE ((size_t)32U) +#define LIBCRUX_ML_KEM_CONSTANTS_G_DIGEST_SIZE ((size_t)64U) -typedef struct libcrux_ml_kem_utils_extraction_helper_Keypair768_s { - uint8_t fst[1152U]; - uint8_t snd[1184U]; -} libcrux_ml_kem_utils_extraction_helper_Keypair768; +#define LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE ((size_t)32U) /** -A monomorphic instance of core.result.Result -with types uint8_t[24size_t], core_array_TryFromSliceError + K * BITS_PER_RING_ELEMENT / 8 + [eurydice] Note that we can't use const generics here because that breaks + C extraction with eurydice. */ -typedef struct Result_6f_s { - Result_86_tags tag; - union { - uint8_t case_Ok[24U]; - TryFromSliceError case_Err; - } val; -} Result_6f; +static inline size_t libcrux_ml_kem_constants_ranked_bytes_per_ring_element( + size_t rank) { + return rank * LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT / (size_t)8U; +} /** -This function found in impl {core::result::Result} +This function found in impl {libcrux_secrets::traits::Classify for T} */ /** -A monomorphic instance of core.result.unwrap_41 -with types uint8_t[24size_t], core_array_TryFromSliceError +A monomorphic instance of libcrux_secrets.int.public_integers.classify_27 +with types uint8_t */ -static inline void unwrap_41_1c(Result_6f self, uint8_t ret[24U]) { - if (self.tag == Ok) { - uint8_t f0[24U]; - memcpy(f0, self.val.case_Ok, (size_t)24U * sizeof(uint8_t)); - memcpy(ret, f0, (size_t)24U * sizeof(uint8_t)); - } else { - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "unwrap not Ok"); - KRML_HOST_EXIT(255U); - } +static KRML_MUSTINLINE uint8_t +libcrux_secrets_int_public_integers_classify_27_90(uint8_t self) { + return self; } /** -A monomorphic instance of core.result.Result -with types uint8_t[20size_t], core_array_TryFromSliceError - -*/ -typedef struct Result_7a_s { - Result_86_tags tag; - union { - uint8_t case_Ok[20U]; - TryFromSliceError case_Err; - } val; -} Result_7a; - -/** -This function found in impl {core::result::Result} +This function found in impl {libcrux_secrets::traits::Declassify for T} */ /** -A monomorphic instance of core.result.unwrap_41 -with types uint8_t[20size_t], core_array_TryFromSliceError +A monomorphic instance of libcrux_secrets.int.public_integers.declassify_d8 +with types int16_t */ -static inline void unwrap_41_34(Result_7a self, uint8_t ret[20U]) { - if (self.tag == Ok) { - uint8_t f0[20U]; - memcpy(f0, self.val.case_Ok, (size_t)20U * sizeof(uint8_t)); - memcpy(ret, f0, (size_t)20U * sizeof(uint8_t)); - } else { - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "unwrap not Ok"); - KRML_HOST_EXIT(255U); - } +static KRML_MUSTINLINE int16_t +libcrux_secrets_int_public_integers_declassify_d8_39(int16_t self) { + return self; } /** -A monomorphic instance of core.result.Result -with types uint8_t[10size_t], core_array_TryFromSliceError - +This function found in impl {libcrux_secrets::int::CastOps for i16} */ -typedef struct Result_cd_s { - Result_86_tags tag; - union { - uint8_t case_Ok[10U]; - TryFromSliceError case_Err; - } val; -} Result_cd; +static KRML_MUSTINLINE uint8_t libcrux_secrets_int_as_u8_f5(int16_t self) { + return libcrux_secrets_int_public_integers_classify_27_90( + (uint8_t)libcrux_secrets_int_public_integers_declassify_d8_39(self)); +} /** -This function found in impl {core::result::Result} +This function found in impl {libcrux_secrets::traits::Classify for T} */ /** -A monomorphic instance of core.result.unwrap_41 -with types uint8_t[10size_t], core_array_TryFromSliceError +A monomorphic instance of libcrux_secrets.int.public_integers.classify_27 +with types int16_t */ -static inline void unwrap_41_e8(Result_cd self, uint8_t ret[10U]) { - if (self.tag == Ok) { - uint8_t f0[10U]; - memcpy(f0, self.val.case_Ok, (size_t)10U * sizeof(uint8_t)); - memcpy(ret, f0, (size_t)10U * sizeof(uint8_t)); - } else { - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "unwrap not Ok"); - KRML_HOST_EXIT(255U); - } +static KRML_MUSTINLINE int16_t +libcrux_secrets_int_public_integers_classify_27_39(int16_t self) { + return self; } -typedef struct Eurydice_slice_uint8_t_4size_t__x2_s { - Eurydice_slice fst[4U]; - Eurydice_slice snd[4U]; -} Eurydice_slice_uint8_t_4size_t__x2; - -typedef struct libcrux_ml_kem_mlkem768_MlKem768Ciphertext_s { - uint8_t value[1088U]; -} libcrux_ml_kem_mlkem768_MlKem768Ciphertext; - -/** - A reference to the raw byte slice. -*/ /** -This function found in impl {libcrux_ml_kem::types::MlKemCiphertext#6} +This function found in impl {libcrux_secrets::traits::Declassify for T} */ /** -A monomorphic instance of libcrux_ml_kem.types.as_slice_d4 -with const generics -- SIZE= 1088 +A monomorphic instance of libcrux_secrets.int.public_integers.declassify_d8 +with types uint8_t + */ -static inline uint8_t *libcrux_ml_kem_types_as_slice_d4_1d( - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *self) { - return self->value; +static KRML_MUSTINLINE uint8_t +libcrux_secrets_int_public_integers_declassify_d8_90(uint8_t self) { + return self; } /** -A monomorphic instance of libcrux_ml_kem.types.MlKemPublicKey -with const generics -- $1184size_t +This function found in impl {libcrux_secrets::int::CastOps for u8} */ -typedef struct libcrux_ml_kem_types_MlKemPublicKey_15_s { - uint8_t value[1184U]; -} libcrux_ml_kem_types_MlKemPublicKey_15; +static KRML_MUSTINLINE int16_t libcrux_secrets_int_as_i16_59(uint8_t self) { + return libcrux_secrets_int_public_integers_classify_27_39( + (int16_t)libcrux_secrets_int_public_integers_declassify_d8_90(self)); +} /** -This function found in impl {(core::convert::From<@Array> for -libcrux_ml_kem::types::MlKemPublicKey)#14} +This function found in impl {libcrux_secrets::traits::Classify for T} */ /** -A monomorphic instance of libcrux_ml_kem.types.from_b6 -with const generics -- SIZE= 1184 +A monomorphic instance of libcrux_secrets.int.public_integers.classify_27 +with types int32_t + */ -static inline libcrux_ml_kem_types_MlKemPublicKey_15 -libcrux_ml_kem_types_from_b6_da(uint8_t value[1184U]) { - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_value[1184U]; - memcpy(copy_of_value, value, (size_t)1184U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPublicKey_15 lit; - memcpy(lit.value, copy_of_value, (size_t)1184U * sizeof(uint8_t)); - return lit; +static KRML_MUSTINLINE int32_t +libcrux_secrets_int_public_integers_classify_27_a8(int32_t self) { + return self; } /** -A monomorphic instance of libcrux_ml_kem.types.MlKemPrivateKey -with const generics -- $2400size_t +This function found in impl {libcrux_secrets::int::CastOps for i16} */ -typedef struct libcrux_ml_kem_types_MlKemPrivateKey_55_s { - uint8_t value[2400U]; -} libcrux_ml_kem_types_MlKemPrivateKey_55; - -typedef struct libcrux_ml_kem_mlkem768_MlKem768KeyPair_s { - libcrux_ml_kem_types_MlKemPrivateKey_55 sk; - libcrux_ml_kem_types_MlKemPublicKey_15 pk; -} libcrux_ml_kem_mlkem768_MlKem768KeyPair; +static KRML_MUSTINLINE int32_t libcrux_secrets_int_as_i32_f5(int16_t self) { + return libcrux_secrets_int_public_integers_classify_27_a8( + (int32_t)libcrux_secrets_int_public_integers_declassify_d8_39(self)); +} /** - Create a new [`MlKemKeyPair`] from the secret and public key. +This function found in impl {libcrux_secrets::traits::Declassify for T} */ /** -This function found in impl -{libcrux_ml_kem::types::MlKemKeyPair} +A monomorphic instance of libcrux_secrets.int.public_integers.declassify_d8 +with types int32_t + */ +static KRML_MUSTINLINE int32_t +libcrux_secrets_int_public_integers_declassify_d8_a8(int32_t self) { + return self; +} + /** -A monomorphic instance of libcrux_ml_kem.types.from_17 -with const generics -- PRIVATE_KEY_SIZE= 2400 -- PUBLIC_KEY_SIZE= 1184 +This function found in impl {libcrux_secrets::int::CastOps for i32} */ -static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair -libcrux_ml_kem_types_from_17_35(libcrux_ml_kem_types_MlKemPrivateKey_55 sk, - libcrux_ml_kem_types_MlKemPublicKey_15 pk) { - return ( - CLITERAL(libcrux_ml_kem_mlkem768_MlKem768KeyPair){.sk = sk, .pk = pk}); +static KRML_MUSTINLINE int16_t libcrux_secrets_int_as_i16_36(int32_t self) { + return libcrux_secrets_int_public_integers_classify_27_39( + (int16_t)libcrux_secrets_int_public_integers_declassify_d8_a8(self)); } /** -This function found in impl {(core::convert::From<@Array> for -libcrux_ml_kem::types::MlKemPrivateKey)#8} +This function found in impl {libcrux_secrets::traits::Declassify for T} */ /** -A monomorphic instance of libcrux_ml_kem.types.from_05 -with const generics -- SIZE= 2400 +A monomorphic instance of libcrux_secrets.int.public_integers.declassify_d8 +with types uint32_t + */ -static inline libcrux_ml_kem_types_MlKemPrivateKey_55 -libcrux_ml_kem_types_from_05_f2(uint8_t value[2400U]) { - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_value[2400U]; - memcpy(copy_of_value, value, (size_t)2400U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey_55 lit; - memcpy(lit.value, copy_of_value, (size_t)2400U * sizeof(uint8_t)); - return lit; +static KRML_MUSTINLINE uint32_t +libcrux_secrets_int_public_integers_declassify_d8_df(uint32_t self) { + return self; } /** -A monomorphic instance of core.result.Result -with types uint8_t[32size_t], core_array_TryFromSliceError - +This function found in impl {libcrux_secrets::int::CastOps for u32} */ -typedef struct Result_00_s { - Result_86_tags tag; - union { - uint8_t case_Ok[32U]; - TryFromSliceError case_Err; - } val; -} Result_00; +static KRML_MUSTINLINE int32_t libcrux_secrets_int_as_i32_b8(uint32_t self) { + return libcrux_secrets_int_public_integers_classify_27_a8( + (int32_t)libcrux_secrets_int_public_integers_declassify_d8_df(self)); +} /** -This function found in impl {core::result::Result} +This function found in impl {libcrux_secrets::traits::Classify for T} */ /** -A monomorphic instance of core.result.unwrap_41 -with types uint8_t[32size_t], core_array_TryFromSliceError +A monomorphic instance of libcrux_secrets.int.public_integers.classify_27 +with types uint16_t */ -static inline void unwrap_41_83(Result_00 self, uint8_t ret[32U]) { +static KRML_MUSTINLINE uint16_t +libcrux_secrets_int_public_integers_classify_27_de(uint16_t self) { + return self; +} + +/** +This function found in impl {libcrux_secrets::int::CastOps for i16} +*/ +static KRML_MUSTINLINE uint16_t libcrux_secrets_int_as_u16_f5(int16_t self) { + return libcrux_secrets_int_public_integers_classify_27_de( + (uint16_t)libcrux_secrets_int_public_integers_declassify_d8_39(self)); +} + +/** +This function found in impl {libcrux_secrets::traits::Declassify for T} +*/ +/** +A monomorphic instance of libcrux_secrets.int.public_integers.declassify_d8 +with types uint16_t + +*/ +static KRML_MUSTINLINE uint16_t +libcrux_secrets_int_public_integers_declassify_d8_de(uint16_t self) { + return self; +} + +/** +This function found in impl {libcrux_secrets::int::CastOps for u16} +*/ +static KRML_MUSTINLINE int16_t libcrux_secrets_int_as_i16_ca(uint16_t self) { + return libcrux_secrets_int_public_integers_classify_27_39( + (int16_t)libcrux_secrets_int_public_integers_declassify_d8_de(self)); +} + +/** +This function found in impl {libcrux_secrets::traits::Classify for T} +*/ +/** +A monomorphic instance of libcrux_secrets.int.public_integers.classify_27 +with types uint64_t + +*/ +static KRML_MUSTINLINE uint64_t +libcrux_secrets_int_public_integers_classify_27_49(uint64_t self) { + return self; +} + +/** +This function found in impl {libcrux_secrets::int::CastOps for u16} +*/ +static KRML_MUSTINLINE uint64_t libcrux_secrets_int_as_u64_ca(uint16_t self) { + return libcrux_secrets_int_public_integers_classify_27_49( + (uint64_t)libcrux_secrets_int_public_integers_declassify_d8_de(self)); +} + +/** +This function found in impl {libcrux_secrets::traits::Classify for T} +*/ +/** +A monomorphic instance of libcrux_secrets.int.public_integers.classify_27 +with types uint32_t + +*/ +static KRML_MUSTINLINE uint32_t +libcrux_secrets_int_public_integers_classify_27_df(uint32_t self) { + return self; +} + +/** +This function found in impl {libcrux_secrets::traits::Declassify for T} +*/ +/** +A monomorphic instance of libcrux_secrets.int.public_integers.declassify_d8 +with types uint64_t + +*/ +static KRML_MUSTINLINE uint64_t +libcrux_secrets_int_public_integers_declassify_d8_49(uint64_t self) { + return self; +} + +/** +This function found in impl {libcrux_secrets::int::CastOps for u64} +*/ +static KRML_MUSTINLINE uint32_t libcrux_secrets_int_as_u32_a3(uint64_t self) { + return libcrux_secrets_int_public_integers_classify_27_df( + (uint32_t)libcrux_secrets_int_public_integers_declassify_d8_49(self)); +} + +/** +This function found in impl {libcrux_secrets::int::CastOps for u32} +*/ +static KRML_MUSTINLINE int16_t libcrux_secrets_int_as_i16_b8(uint32_t self) { + return libcrux_secrets_int_public_integers_classify_27_39( + (int16_t)libcrux_secrets_int_public_integers_declassify_d8_df(self)); +} + +/** +This function found in impl {libcrux_secrets::int::CastOps for i16} +*/ +static KRML_MUSTINLINE int16_t libcrux_secrets_int_as_i16_f5(int16_t self) { + return libcrux_secrets_int_public_integers_classify_27_39( + libcrux_secrets_int_public_integers_declassify_d8_39(self)); +} + +typedef struct libcrux_ml_kem_utils_extraction_helper_Keypair768_s { + uint8_t fst[1152U]; + uint8_t snd[1184U]; +} libcrux_ml_kem_utils_extraction_helper_Keypair768; + +#define Ok 0 +#define Err 1 + +typedef uint8_t Result_b2_tags; + +/** +A monomorphic instance of core.result.Result +with types uint8_t[24size_t], core_array_TryFromSliceError + +*/ +typedef struct Result_b2_s { + Result_b2_tags tag; + union { + uint8_t case_Ok[24U]; + TryFromSliceError case_Err; + } val; +} Result_b2; + +/** +This function found in impl {core::result::Result[TraitClause@0, +TraitClause@1]} +*/ +/** +A monomorphic instance of core.result.unwrap_26 +with types uint8_t[24size_t], core_array_TryFromSliceError + +*/ +static inline void unwrap_26_70(Result_b2 self, uint8_t ret[24U]) { + if (self.tag == Ok) { + uint8_t f0[24U]; + memcpy(f0, self.val.case_Ok, (size_t)24U * sizeof(uint8_t)); + memcpy(ret, f0, (size_t)24U * sizeof(uint8_t)); + } else { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "unwrap not Ok"); + KRML_HOST_EXIT(255U); + } +} + +/** +A monomorphic instance of core.result.Result +with types uint8_t[20size_t], core_array_TryFromSliceError + +*/ +typedef struct Result_e1_s { + Result_b2_tags tag; + union { + uint8_t case_Ok[20U]; + TryFromSliceError case_Err; + } val; +} Result_e1; + +/** +This function found in impl {core::result::Result[TraitClause@0, +TraitClause@1]} +*/ +/** +A monomorphic instance of core.result.unwrap_26 +with types uint8_t[20size_t], core_array_TryFromSliceError + +*/ +static inline void unwrap_26_20(Result_e1 self, uint8_t ret[20U]) { + if (self.tag == Ok) { + uint8_t f0[20U]; + memcpy(f0, self.val.case_Ok, (size_t)20U * sizeof(uint8_t)); + memcpy(ret, f0, (size_t)20U * sizeof(uint8_t)); + } else { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "unwrap not Ok"); + KRML_HOST_EXIT(255U); + } +} + +/** + Pad the `slice` with `0`s at the end. +*/ +/** +A monomorphic instance of libcrux_ml_kem.utils.into_padded_array +with const generics +- LEN= 32 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_utils_into_padded_array_9e( + Eurydice_slice slice, uint8_t ret[32U]) { + uint8_t out[32U] = {0U}; + uint8_t *uu____0 = out; + Eurydice_slice_copy( + Eurydice_array_to_subslice3( + uu____0, (size_t)0U, Eurydice_slice_len(slice, uint8_t), uint8_t *), + slice, uint8_t); + memcpy(ret, out, (size_t)32U * sizeof(uint8_t)); +} + +/** +A monomorphic instance of libcrux_ml_kem.types.MlKemPrivateKey +with const generics +- $2400size_t +*/ +typedef struct libcrux_ml_kem_types_MlKemPrivateKey_d9_s { + uint8_t value[2400U]; +} libcrux_ml_kem_types_MlKemPrivateKey_d9; + +/** +This function found in impl {core::default::Default for +libcrux_ml_kem::types::MlKemPrivateKey} +*/ +/** +A monomorphic instance of libcrux_ml_kem.types.default_d3 +with const generics +- SIZE= 2400 +*/ +static inline libcrux_ml_kem_types_MlKemPrivateKey_d9 +libcrux_ml_kem_types_default_d3_28(void) { + return ( + KRML_CLITERAL(libcrux_ml_kem_types_MlKemPrivateKey_d9){.value = {0U}}); +} + +/** +A monomorphic instance of libcrux_ml_kem.types.MlKemPublicKey +with const generics +- $1184size_t +*/ +typedef struct libcrux_ml_kem_types_MlKemPublicKey_30_s { + uint8_t value[1184U]; +} libcrux_ml_kem_types_MlKemPublicKey_30; + +/** +This function found in impl {core::convert::From<@Array> for +libcrux_ml_kem::types::MlKemPublicKey} +*/ +/** +A monomorphic instance of libcrux_ml_kem.types.from_fd +with const generics +- SIZE= 1184 +*/ +static inline libcrux_ml_kem_types_MlKemPublicKey_30 +libcrux_ml_kem_types_from_fd_d0(uint8_t value[1184U]) { + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_value[1184U]; + memcpy(copy_of_value, value, (size_t)1184U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPublicKey_30 lit; + memcpy(lit.value, copy_of_value, (size_t)1184U * sizeof(uint8_t)); + return lit; +} + +typedef struct libcrux_ml_kem_mlkem768_MlKem768KeyPair_s { + libcrux_ml_kem_types_MlKemPrivateKey_d9 sk; + libcrux_ml_kem_types_MlKemPublicKey_30 pk; +} libcrux_ml_kem_mlkem768_MlKem768KeyPair; + +/** +This function found in impl +{libcrux_ml_kem::types::MlKemKeyPair} +*/ +/** +A monomorphic instance of libcrux_ml_kem.types.from_17 +with const generics +- PRIVATE_KEY_SIZE= 2400 +- PUBLIC_KEY_SIZE= 1184 +*/ +static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_types_from_17_74(libcrux_ml_kem_types_MlKemPrivateKey_d9 sk, + libcrux_ml_kem_types_MlKemPublicKey_30 pk) { + return (KRML_CLITERAL(libcrux_ml_kem_mlkem768_MlKem768KeyPair){.sk = sk, + .pk = pk}); +} + +/** +This function found in impl {core::convert::From<@Array> for +libcrux_ml_kem::types::MlKemPrivateKey} +*/ +/** +A monomorphic instance of libcrux_ml_kem.types.from_77 +with const generics +- SIZE= 2400 +*/ +static inline libcrux_ml_kem_types_MlKemPrivateKey_d9 +libcrux_ml_kem_types_from_77_28(uint8_t value[2400U]) { + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_value[2400U]; + memcpy(copy_of_value, value, (size_t)2400U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey_d9 lit; + memcpy(lit.value, copy_of_value, (size_t)2400U * sizeof(uint8_t)); + return lit; +} + +/** +A monomorphic instance of core.result.Result +with types uint8_t[32size_t], core_array_TryFromSliceError + +*/ +typedef struct Result_fb_s { + Result_b2_tags tag; + union { + uint8_t case_Ok[32U]; + TryFromSliceError case_Err; + } val; +} Result_fb; + +/** +This function found in impl {core::result::Result[TraitClause@0, +TraitClause@1]} +*/ +/** +A monomorphic instance of core.result.unwrap_26 +with types uint8_t[32size_t], core_array_TryFromSliceError + +*/ +static inline void unwrap_26_b3(Result_fb self, uint8_t ret[32U]) { if (self.tag == Ok) { uint8_t f0[32U]; memcpy(f0, self.val.case_Ok, (size_t)32U * sizeof(uint8_t)); @@ -534,28 +1103,32 @@ static inline void unwrap_41_83(Result_00 self, uint8_t ret[32U]) { } } +typedef struct libcrux_ml_kem_mlkem768_MlKem768Ciphertext_s { + uint8_t value[1088U]; +} libcrux_ml_kem_mlkem768_MlKem768Ciphertext; + /** A monomorphic instance of K. with types libcrux_ml_kem_types_MlKemCiphertext[[$1088size_t]], uint8_t[32size_t] */ -typedef struct tuple_3c_s { +typedef struct tuple_c2_s { libcrux_ml_kem_mlkem768_MlKem768Ciphertext fst; uint8_t snd[32U]; -} tuple_3c; +} tuple_c2; /** -This function found in impl {(core::convert::From<@Array> for -libcrux_ml_kem::types::MlKemCiphertext)#2} +This function found in impl {core::convert::From<@Array> for +libcrux_ml_kem::types::MlKemCiphertext} */ /** -A monomorphic instance of libcrux_ml_kem.types.from_01 +A monomorphic instance of libcrux_ml_kem.types.from_e0 with const generics - SIZE= 1088 */ static inline libcrux_ml_kem_mlkem768_MlKem768Ciphertext -libcrux_ml_kem_types_from_01_9f(uint8_t value[1088U]) { +libcrux_ml_kem_types_from_e0_80(uint8_t value[1088U]) { /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_value[1088U]; memcpy(copy_of_value, value, (size_t)1088U * sizeof(uint8_t)); @@ -565,21 +1138,46 @@ libcrux_ml_kem_types_from_01_9f(uint8_t value[1088U]) { } /** - A reference to the raw byte slice. +This function found in impl {libcrux_ml_kem::types::MlKemPublicKey} +*/ +/** +A monomorphic instance of libcrux_ml_kem.types.as_slice_e6 +with const generics +- SIZE= 1184 */ +static inline uint8_t *libcrux_ml_kem_types_as_slice_e6_d0( + libcrux_ml_kem_types_MlKemPublicKey_30 *self) { + return self->value; +} + /** -This function found in impl {libcrux_ml_kem::types::MlKemPublicKey#18} +This function found in impl {libcrux_ml_kem::types::MlKemCiphertext} */ /** -A monomorphic instance of libcrux_ml_kem.types.as_slice_cb +A monomorphic instance of libcrux_ml_kem.types.as_slice_a9 with const generics -- SIZE= 1184 +- SIZE= 1088 */ -static inline uint8_t *libcrux_ml_kem_types_as_slice_cb_50( - libcrux_ml_kem_types_MlKemPublicKey_15 *self) { +static inline uint8_t *libcrux_ml_kem_types_as_slice_a9_80( + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *self) { return self->value; } +/** +A monomorphic instance of libcrux_ml_kem.utils.prf_input_inc +with const generics +- K= 3 +*/ +static KRML_MUSTINLINE uint8_t libcrux_ml_kem_utils_prf_input_inc_e0( + uint8_t (*prf_inputs)[33U], uint8_t domain_separator) { + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U; + } + return domain_separator; +} + /** Pad the `slice` with `0`s at the end. */ @@ -588,13 +1186,13 @@ A monomorphic instance of libcrux_ml_kem.utils.into_padded_array with const generics - LEN= 33 */ -static KRML_MUSTINLINE void libcrux_ml_kem_utils_into_padded_array_ea2( +static KRML_MUSTINLINE void libcrux_ml_kem_utils_into_padded_array_c8( Eurydice_slice slice, uint8_t ret[33U]) { uint8_t out[33U] = {0U}; uint8_t *uu____0 = out; Eurydice_slice_copy( - Eurydice_array_to_subslice2(uu____0, (size_t)0U, - Eurydice_slice_len(slice, uint8_t), uint8_t), + Eurydice_array_to_subslice3( + uu____0, (size_t)0U, Eurydice_slice_len(slice, uint8_t), uint8_t *), slice, uint8_t); memcpy(ret, out, (size_t)33U * sizeof(uint8_t)); } @@ -607,27 +1205,27 @@ A monomorphic instance of libcrux_ml_kem.utils.into_padded_array with const generics - LEN= 34 */ -static KRML_MUSTINLINE void libcrux_ml_kem_utils_into_padded_array_ea1( +static KRML_MUSTINLINE void libcrux_ml_kem_utils_into_padded_array_b6( Eurydice_slice slice, uint8_t ret[34U]) { uint8_t out[34U] = {0U}; uint8_t *uu____0 = out; Eurydice_slice_copy( - Eurydice_array_to_subslice2(uu____0, (size_t)0U, - Eurydice_slice_len(slice, uint8_t), uint8_t), + Eurydice_array_to_subslice3( + uu____0, (size_t)0U, Eurydice_slice_len(slice, uint8_t), uint8_t *), slice, uint8_t); memcpy(ret, out, (size_t)34U * sizeof(uint8_t)); } /** -This function found in impl {(core::convert::AsRef<@Slice> for -libcrux_ml_kem::types::MlKemCiphertext)#1} +This function found in impl {core::convert::AsRef<@Slice> for +libcrux_ml_kem::types::MlKemCiphertext} */ /** -A monomorphic instance of libcrux_ml_kem.types.as_ref_00 +A monomorphic instance of libcrux_ml_kem.types.as_ref_d3 with const generics - SIZE= 1088 */ -static inline Eurydice_slice libcrux_ml_kem_types_as_ref_00_24( +static inline Eurydice_slice libcrux_ml_kem_types_as_ref_d3_80( libcrux_ml_kem_mlkem768_MlKem768Ciphertext *self) { return Eurydice_array_to_slice((size_t)1088U, self->value, uint8_t); } @@ -640,13 +1238,13 @@ A monomorphic instance of libcrux_ml_kem.utils.into_padded_array with const generics - LEN= 1120 */ -static KRML_MUSTINLINE void libcrux_ml_kem_utils_into_padded_array_ea0( +static KRML_MUSTINLINE void libcrux_ml_kem_utils_into_padded_array_15( Eurydice_slice slice, uint8_t ret[1120U]) { uint8_t out[1120U] = {0U}; uint8_t *uu____0 = out; Eurydice_slice_copy( - Eurydice_array_to_subslice2(uu____0, (size_t)0U, - Eurydice_slice_len(slice, uint8_t), uint8_t), + Eurydice_array_to_subslice3( + uu____0, (size_t)0U, Eurydice_slice_len(slice, uint8_t), uint8_t *), slice, uint8_t); memcpy(ret, out, (size_t)1120U * sizeof(uint8_t)); } @@ -659,39 +1257,182 @@ A monomorphic instance of libcrux_ml_kem.utils.into_padded_array with const generics - LEN= 64 */ -static KRML_MUSTINLINE void libcrux_ml_kem_utils_into_padded_array_ea( +static KRML_MUSTINLINE void libcrux_ml_kem_utils_into_padded_array_24( Eurydice_slice slice, uint8_t ret[64U]) { uint8_t out[64U] = {0U}; uint8_t *uu____0 = out; Eurydice_slice_copy( - Eurydice_array_to_subslice2(uu____0, (size_t)0U, - Eurydice_slice_len(slice, uint8_t), uint8_t), + Eurydice_array_to_subslice3( + uu____0, (size_t)0U, Eurydice_slice_len(slice, uint8_t), uint8_t *), slice, uint8_t); memcpy(ret, out, (size_t)64U * sizeof(uint8_t)); } -/** -A monomorphic instance of core.result.Result -with types int16_t[16size_t], core_array_TryFromSliceError +typedef struct Eurydice_slice_uint8_t_x4_s { + Eurydice_slice fst; + Eurydice_slice snd; + Eurydice_slice thd; + Eurydice_slice f3; +} Eurydice_slice_uint8_t_x4; -*/ -typedef struct Result_c0_s { - Result_86_tags tag; - union { - int16_t case_Ok[16U]; +typedef struct Eurydice_slice_uint8_t_x2_s { + Eurydice_slice fst; + Eurydice_slice snd; +} Eurydice_slice_uint8_t_x2; + +/** + Unpack an incoming private key into it's different parts. + + We have this here in types to extract into a common core for C. +*/ +/** +A monomorphic instance of libcrux_ml_kem.types.unpack_private_key +with const generics +- CPA_SECRET_KEY_SIZE= 1152 +- PUBLIC_KEY_SIZE= 1184 +*/ +static inline Eurydice_slice_uint8_t_x4 +libcrux_ml_kem_types_unpack_private_key_b4(Eurydice_slice private_key) { + Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at( + private_key, (size_t)1152U, uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice secret_key0 = uu____0.snd; + Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( + secret_key0, (size_t)1184U, uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice ind_cpa_public_key = uu____1.fst; + Eurydice_slice secret_key = uu____1.snd; + Eurydice_slice_uint8_t_x2 uu____2 = Eurydice_slice_split_at( + secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + Eurydice_slice_uint8_t_x2); + Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; + Eurydice_slice implicit_rejection_value = uu____2.snd; + return ( + KRML_CLITERAL(Eurydice_slice_uint8_t_x4){.fst = ind_cpa_secret_key, + .snd = ind_cpa_public_key, + .thd = ind_cpa_public_key_hash, + .f3 = implicit_rejection_value}); +} + +/** +This function found in impl {libcrux_secrets::traits::Declassify for T} +*/ +/** +A monomorphic instance of libcrux_secrets.int.public_integers.declassify_d8 +with types uint8_t[24size_t] + +*/ +static KRML_MUSTINLINE void +libcrux_secrets_int_public_integers_declassify_d8_d2(uint8_t self[24U], + uint8_t ret[24U]) { + memcpy(ret, self, (size_t)24U * sizeof(uint8_t)); +} + +/** +This function found in impl {libcrux_secrets::traits::Declassify for T} +*/ +/** +A monomorphic instance of libcrux_secrets.int.public_integers.declassify_d8 +with types uint8_t[20size_t] + +*/ +static KRML_MUSTINLINE void +libcrux_secrets_int_public_integers_declassify_d8_57(uint8_t self[20U], + uint8_t ret[20U]) { + memcpy(ret, self, (size_t)20U * sizeof(uint8_t)); +} + +/** +This function found in impl {libcrux_secrets::traits::Declassify for T} +*/ +/** +A monomorphic instance of libcrux_secrets.int.public_integers.declassify_d8 +with types uint8_t[8size_t] + +*/ +static KRML_MUSTINLINE void +libcrux_secrets_int_public_integers_declassify_d8_76(uint8_t self[8U], + uint8_t ret[8U]) { + memcpy(ret, self, (size_t)8U * sizeof(uint8_t)); +} + +/** +This function found in impl {libcrux_secrets::traits::Declassify for T} +*/ +/** +A monomorphic instance of libcrux_secrets.int.public_integers.declassify_d8 +with types uint8_t[2size_t] + +*/ +static KRML_MUSTINLINE void +libcrux_secrets_int_public_integers_declassify_d8_d4(uint8_t self[2U], + uint8_t ret[2U]) { + memcpy(ret, self, (size_t)2U * sizeof(uint8_t)); +} + +/** +This function found in impl {libcrux_secrets::traits::Classify for T} +*/ +/** +A monomorphic instance of libcrux_secrets.int.public_integers.classify_27 +with types int16_t[16size_t] + +*/ +static KRML_MUSTINLINE void libcrux_secrets_int_public_integers_classify_27_46( + int16_t self[16U], int16_t ret[16U]) { + memcpy(ret, self, (size_t)16U * sizeof(int16_t)); +} + +/** +This function found in impl {libcrux_secrets::traits::ClassifyRef<&'a +(@Slice)> for &'a (@Slice)} +*/ +/** +A monomorphic instance of libcrux_secrets.int.classify_public.classify_ref_9b +with types uint8_t + +*/ +static KRML_MUSTINLINE Eurydice_slice +libcrux_secrets_int_classify_public_classify_ref_9b_90(Eurydice_slice self) { + return self; +} + +/** +This function found in impl {libcrux_secrets::traits::ClassifyRef<&'a +(@Slice)> for &'a (@Slice)} +*/ +/** +A monomorphic instance of libcrux_secrets.int.classify_public.classify_ref_9b +with types int16_t + +*/ +static KRML_MUSTINLINE Eurydice_slice +libcrux_secrets_int_classify_public_classify_ref_9b_39(Eurydice_slice self) { + return self; +} + +/** +A monomorphic instance of core.result.Result +with types int16_t[16size_t], core_array_TryFromSliceError + +*/ +typedef struct Result_0a_s { + Result_b2_tags tag; + union { + int16_t case_Ok[16U]; TryFromSliceError case_Err; } val; -} Result_c0; +} Result_0a; /** -This function found in impl {core::result::Result} +This function found in impl {core::result::Result[TraitClause@0, +TraitClause@1]} */ /** -A monomorphic instance of core.result.unwrap_41 +A monomorphic instance of core.result.unwrap_26 with types int16_t[16size_t], core_array_TryFromSliceError */ -static inline void unwrap_41_f9(Result_c0 self, int16_t ret[16U]) { +static inline void unwrap_26_00(Result_0a self, int16_t ret[16U]) { if (self.tag == Ok) { int16_t f0[16U]; memcpy(f0, self.val.case_Ok, (size_t)16U * sizeof(int16_t)); @@ -708,23 +1449,24 @@ A monomorphic instance of core.result.Result with types uint8_t[8size_t], core_array_TryFromSliceError */ -typedef struct Result_56_s { - Result_86_tags tag; +typedef struct Result_15_s { + Result_b2_tags tag; union { uint8_t case_Ok[8U]; TryFromSliceError case_Err; } val; -} Result_56; +} Result_15; /** -This function found in impl {core::result::Result} +This function found in impl {core::result::Result[TraitClause@0, +TraitClause@1]} */ /** -A monomorphic instance of core.result.unwrap_41 +A monomorphic instance of core.result.unwrap_26 with types uint8_t[8size_t], core_array_TryFromSliceError */ -static inline void unwrap_41_ac(Result_56 self, uint8_t ret[8U]) { +static inline void unwrap_26_68(Result_15 self, uint8_t ret[8U]) { if (self.tag == Ok) { uint8_t f0[8U]; memcpy(f0, self.val.case_Ok, (size_t)8U * sizeof(uint8_t)); @@ -736,39 +1478,30 @@ static inline void unwrap_41_ac(Result_56 self, uint8_t ret[8U]) { } } -typedef struct Eurydice_slice_uint8_t_x2_s { - Eurydice_slice fst; - Eurydice_slice snd; -} Eurydice_slice_uint8_t_x2; - -typedef struct Eurydice_slice_uint8_t_1size_t__x2_s { - Eurydice_slice fst[1U]; - Eurydice_slice snd[1U]; -} Eurydice_slice_uint8_t_1size_t__x2; - #if defined(__cplusplus) } #endif -#define __libcrux_core_H_DEFINED -#endif +#define libcrux_mlkem_core_H_DEFINED +#endif /* libcrux_mlkem_core_H */ -/* from libcrux/libcrux-ml-kem/cg/libcrux_ct_ops.h */ +/* from libcrux/libcrux-ml-kem/extracts/c_header_only/generated/libcrux_ct_ops.h */ /* - * SPDX-FileCopyrightText: 2024 Cryspen Sarl + * SPDX-FileCopyrightText: 2025 Cryspen Sarl * * SPDX-License-Identifier: MIT or Apache-2.0 * * This code was generated with the following revisions: - * Charon: 6b5e110342a771a3e1c739b10294b1778e4be8b4 - * Eurydice: 31be7d65ca5d6acdacfb33652e478d24dd85c1cb - * Karamel: 3205d3365ea2790b02368f79fcee38e38d0b5908 - * F*: a32b316e521fa4f239b610ec8f1d15e78d62cbe8-dirty - * Libcrux: 4ad532b206174114dd4140b718e7794a28fc59ee + * Charon: 667d2fc98984ff7f3df989c2367e6c1fa4a000e7 + * Eurydice: 2381cbc416ef2ad0b561c362c500bc84f36b6785 + * Karamel: 80f5435f2fc505973c469a4afcc8d875cddd0d8b + * F*: 71d8221589d4d438af3706d89cb653cf53e18aab + * Libcrux: 68dfed5a4a9e40277f62828471c029afed1ecdcc */ -#ifndef __libcrux_ct_ops_H -#define __libcrux_ct_ops_H +#ifndef libcrux_ct_ops_H +#define libcrux_ct_ops_H + #if defined(__cplusplus) extern "C" { @@ -778,14 +1511,12 @@ extern "C" { /** Return 1 if `value` is not zero and 0 otherwise. */ -static inline uint8_t libcrux_ml_kem_constant_time_ops_inz(uint8_t value) { +static KRML_NOINLINE uint8_t +libcrux_ml_kem_constant_time_ops_inz(uint8_t value) { uint16_t value0 = (uint16_t)value; - uint16_t result = (((uint32_t)value0 | - (uint32_t)core_num__u16_7__wrapping_add(~value0, 1U)) & - 0xFFFFU) >> - 8U & - 1U; - return (uint8_t)result; + uint8_t result = + (uint8_t)((uint32_t)core_num__u16__wrapping_add(~value0, 1U) >> 8U); + return (uint32_t)result & 1U; } static KRML_NOINLINE uint8_t @@ -797,14 +1528,15 @@ libcrux_ml_kem_constant_time_ops_is_non_zero(uint8_t value) { Return 1 if the bytes of `lhs` and `rhs` do not exactly match and 0 otherwise. */ -static inline uint8_t libcrux_ml_kem_constant_time_ops_compare( +static KRML_NOINLINE uint8_t libcrux_ml_kem_constant_time_ops_compare( Eurydice_slice lhs, Eurydice_slice rhs) { uint8_t r = 0U; for (size_t i = (size_t)0U; i < Eurydice_slice_len(lhs, uint8_t); i++) { size_t i0 = i; - r = (uint32_t)r | - ((uint32_t)Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *) ^ - (uint32_t)Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *)); + uint8_t nr = (uint32_t)r | + ((uint32_t)Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *) ^ + (uint32_t)Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *)); + r = nr; } return libcrux_ml_kem_constant_time_ops_is_non_zero(r); } @@ -819,19 +1551,21 @@ libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time( If `selector` is not zero, return the bytes in `rhs`; return the bytes in `lhs` otherwise. */ -static inline void libcrux_ml_kem_constant_time_ops_select_ct( +static KRML_NOINLINE void libcrux_ml_kem_constant_time_ops_select_ct( Eurydice_slice lhs, Eurydice_slice rhs, uint8_t selector, uint8_t ret[32U]) { - uint8_t mask = core_num__u8_6__wrapping_sub( + uint8_t mask = core_num__u8__wrapping_sub( libcrux_ml_kem_constant_time_ops_is_non_zero(selector), 1U); uint8_t out[32U] = {0U}; for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE; i++) { size_t i0 = i; - out[i0] = ((uint32_t)Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *) & - (uint32_t)mask) | - ((uint32_t)Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *) & - (uint32_t)~mask); + uint8_t outi = + ((uint32_t)Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *) & + (uint32_t)mask) | + ((uint32_t)Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *) & + (uint32_t)~mask); + out[i0] = outi; } memcpy(ret, out, (size_t)32U * sizeof(uint8_t)); } @@ -843,7 +1577,7 @@ libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( libcrux_ml_kem_constant_time_ops_select_ct(lhs, rhs, selector, ret); } -static inline void +static KRML_NOINLINE void libcrux_ml_kem_constant_time_ops_compare_ciphertexts_select_shared_secret_in_constant_time( Eurydice_slice lhs_c, Eurydice_slice rhs_c, Eurydice_slice lhs_s, Eurydice_slice rhs_s, uint8_t ret[32U]) { @@ -860,2259 +1594,2271 @@ libcrux_ml_kem_constant_time_ops_compare_ciphertexts_select_shared_secret_in_con } #endif -#define __libcrux_ct_ops_H_DEFINED -#endif +#define libcrux_ct_ops_H_DEFINED +#endif /* libcrux_ct_ops_H */ -/* from libcrux/libcrux-ml-kem/cg/libcrux_sha3_portable.h */ +/* from libcrux/libcrux-ml-kem/extracts/c_header_only/generated/libcrux_sha3_portable.h */ /* - * SPDX-FileCopyrightText: 2024 Cryspen Sarl + * SPDX-FileCopyrightText: 2025 Cryspen Sarl * * SPDX-License-Identifier: MIT or Apache-2.0 * * This code was generated with the following revisions: - * Charon: 6b5e110342a771a3e1c739b10294b1778e4be8b4 - * Eurydice: 31be7d65ca5d6acdacfb33652e478d24dd85c1cb - * Karamel: 3205d3365ea2790b02368f79fcee38e38d0b5908 - * F*: a32b316e521fa4f239b610ec8f1d15e78d62cbe8-dirty - * Libcrux: 4ad532b206174114dd4140b718e7794a28fc59ee + * Charon: 667d2fc98984ff7f3df989c2367e6c1fa4a000e7 + * Eurydice: 2381cbc416ef2ad0b561c362c500bc84f36b6785 + * Karamel: 80f5435f2fc505973c469a4afcc8d875cddd0d8b + * F*: 71d8221589d4d438af3706d89cb653cf53e18aab + * Libcrux: 68dfed5a4a9e40277f62828471c029afed1ecdcc */ -#ifndef __libcrux_sha3_portable_H -#define __libcrux_sha3_portable_H +#ifndef libcrux_sha3_portable_H +#define libcrux_sha3_portable_H + #if defined(__cplusplus) extern "C" { #endif -static const uint64_t libcrux_sha3_generic_keccak_ROUNDCONSTANTS[24U] = { - 1ULL, - 32898ULL, - 9223372036854808714ULL, - 9223372039002292224ULL, - 32907ULL, - 2147483649ULL, - 9223372039002292353ULL, - 9223372036854808585ULL, - 138ULL, - 136ULL, - 2147516425ULL, - 2147483658ULL, - 2147516555ULL, - 9223372036854775947ULL, - 9223372036854808713ULL, - 9223372036854808579ULL, - 9223372036854808578ULL, - 9223372036854775936ULL, - 32778ULL, - 9223372039002259466ULL, - 9223372039002292353ULL, - 9223372036854808704ULL, - 2147483649ULL, - 9223372039002292232ULL}; - -/** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} -*/ -static KRML_MUSTINLINE uint64_t libcrux_sha3_portable_keccak_zero_5a(void) { +/** +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} +*/ +static KRML_MUSTINLINE uint64_t libcrux_sha3_simd_portable_zero_d2(void) { return 0ULL; } -static KRML_MUSTINLINE uint64_t libcrux_sha3_portable_keccak__veor5q_u64( +static KRML_MUSTINLINE uint64_t libcrux_sha3_simd_portable__veor5q_u64( uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint64_t e) { - uint64_t ab = a ^ b; - uint64_t cd = c ^ d; - uint64_t abcd = ab ^ cd; - return abcd ^ e; + return (((a ^ b) ^ c) ^ d) ^ e; } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ -static KRML_MUSTINLINE uint64_t libcrux_sha3_portable_keccak_xor5_5a( +static KRML_MUSTINLINE uint64_t libcrux_sha3_simd_portable_xor5_d2( uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint64_t e) { - return libcrux_sha3_portable_keccak__veor5q_u64(a, b, c, d, e); + return libcrux_sha3_simd_portable__veor5q_u64(a, b, c, d, e); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +A monomorphic instance of libcrux_sha3.simd.portable.rotate_left with const generics - LEFT= 1 - RIGHT= 63 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_rotate_left_cb(uint64_t x) { - return x << (uint32_t)(int32_t)1 | x >> (uint32_t)(int32_t)63; +libcrux_sha3_simd_portable_rotate_left_76(uint64_t x) { + return core_num__u64__rotate_left(x, (uint32_t)(int32_t)1); } static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak__vrax1q_u64(uint64_t a, uint64_t b) { +libcrux_sha3_simd_portable__vrax1q_u64(uint64_t a, uint64_t b) { uint64_t uu____0 = a; - return uu____0 ^ libcrux_sha3_portable_keccak_rotate_left_cb(b); + return uu____0 ^ libcrux_sha3_simd_portable_rotate_left_76(b); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_rotate_left1_and_xor_5a(uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vrax1q_u64(a, b); +libcrux_sha3_simd_portable_rotate_left1_and_xor_d2(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable__vrax1q_u64(a, b); } static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak__vbcaxq_u64(uint64_t a, uint64_t b, uint64_t c) { +libcrux_sha3_simd_portable__vbcaxq_u64(uint64_t a, uint64_t b, uint64_t c) { return a ^ (b & ~c); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ -static KRML_MUSTINLINE uint64_t libcrux_sha3_portable_keccak_and_not_xor_5a( - uint64_t a, uint64_t b, uint64_t c) { - return libcrux_sha3_portable_keccak__vbcaxq_u64(a, b, c); +static KRML_MUSTINLINE uint64_t +libcrux_sha3_simd_portable_and_not_xor_d2(uint64_t a, uint64_t b, uint64_t c) { + return libcrux_sha3_simd_portable__vbcaxq_u64(a, b, c); } static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak__veorq_n_u64(uint64_t a, uint64_t c) { +libcrux_sha3_simd_portable__veorq_n_u64(uint64_t a, uint64_t c) { return a ^ c; } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_xor_constant_5a(uint64_t a, uint64_t c) { - return libcrux_sha3_portable_keccak__veorq_n_u64(a, c); +libcrux_sha3_simd_portable_xor_constant_d2(uint64_t a, uint64_t c) { + return libcrux_sha3_simd_portable__veorq_n_u64(a, c); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ -static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_xor_5a(uint64_t a, uint64_t b) { +static KRML_MUSTINLINE uint64_t libcrux_sha3_simd_portable_xor_d2(uint64_t a, + uint64_t b) { return a ^ b; } -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_slice_1( - Eurydice_slice a[1U], size_t start, size_t len, Eurydice_slice ret[1U]) { - ret[0U] = Eurydice_slice_subslice2(a[0U], start, start + len, uint8_t); -} +static const uint64_t + libcrux_sha3_generic_keccak_constants_ROUNDCONSTANTS[24U] = { + 1ULL, + 32898ULL, + 9223372036854808714ULL, + 9223372039002292224ULL, + 32907ULL, + 2147483649ULL, + 9223372039002292353ULL, + 9223372036854808585ULL, + 138ULL, + 136ULL, + 2147516425ULL, + 2147483658ULL, + 2147516555ULL, + 9223372036854775947ULL, + 9223372036854808713ULL, + 9223372036854808579ULL, + 9223372036854808578ULL, + 9223372036854775936ULL, + 32778ULL, + 9223372039002259466ULL, + 9223372039002292353ULL, + 9223372036854808704ULL, + 2147483649ULL, + 9223372039002292232ULL}; + +typedef struct size_t_x2_s { + size_t fst; + size_t snd; +} size_t_x2; /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +A monomorphic instance of libcrux_sha3.generic_keccak.KeccakState +with types uint64_t +with const generics +- $1size_t */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_slice_n_5a( - Eurydice_slice a[1U], size_t start, size_t len, Eurydice_slice ret[1U]) { - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_a[1U]; - memcpy(copy_of_a, a, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret0[1U]; - libcrux_sha3_portable_keccak_slice_1(copy_of_a, start, len, ret0); - memcpy(ret, ret0, (size_t)1U * sizeof(Eurydice_slice)); -} - -static KRML_MUSTINLINE Eurydice_slice_uint8_t_1size_t__x2 -libcrux_sha3_portable_keccak_split_at_mut_1(Eurydice_slice out[1U], - size_t mid) { - Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at_mut( - out[0U], mid, uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice out00 = uu____0.fst; - Eurydice_slice out01 = uu____0.snd; - Eurydice_slice_uint8_t_1size_t__x2 lit; - lit.fst[0U] = out00; - lit.snd[0U] = out01; - return lit; -} +typedef struct libcrux_sha3_generic_keccak_KeccakState_17_s { + uint64_t st[25U]; +} libcrux_sha3_generic_keccak_KeccakState_17; /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::generic_keccak::KeccakState[TraitClause@0, TraitClause@1]} */ -static KRML_MUSTINLINE Eurydice_slice_uint8_t_1size_t__x2 -libcrux_sha3_portable_keccak_split_at_mut_n_5a(Eurydice_slice a[1U], - size_t mid) { - return libcrux_sha3_portable_keccak_split_at_mut_1(a, mid); -} - /** -A monomorphic instance of libcrux_sha3.generic_keccak.KeccakState +A monomorphic instance of libcrux_sha3.generic_keccak.new_80 with types uint64_t with const generics -- $1size_t +- N= 1 */ -typedef struct libcrux_sha3_generic_keccak_KeccakState_48_s { - uint64_t st[5U][5U]; -} libcrux_sha3_generic_keccak_KeccakState_48; +static KRML_MUSTINLINE libcrux_sha3_generic_keccak_KeccakState_17 +libcrux_sha3_generic_keccak_new_80_04(void) { + libcrux_sha3_generic_keccak_KeccakState_17 lit; + uint64_t repeat_expression[25U]; + for (size_t i = (size_t)0U; i < (size_t)25U; i++) { + repeat_expression[i] = libcrux_sha3_simd_portable_zero_d2(); + } + memcpy(lit.st, repeat_expression, (size_t)25U * sizeof(uint64_t)); + return lit; +} /** - Create a new Shake128 x4 state. -*/ -/** -This function found in impl {libcrux_sha3::generic_keccak::KeccakState[TraitClause@0]#1} +A monomorphic instance of libcrux_sha3.traits.get_ij +with types uint64_t +with const generics +- N= 1 */ +static KRML_MUSTINLINE uint64_t *libcrux_sha3_traits_get_ij_04(uint64_t *arr, + size_t i, + size_t j) { + return &arr[(size_t)5U * j + i]; +} + /** -A monomorphic instance of libcrux_sha3.generic_keccak.new_1e +A monomorphic instance of libcrux_sha3.traits.set_ij with types uint64_t with const generics - N= 1 */ -static KRML_MUSTINLINE libcrux_sha3_generic_keccak_KeccakState_48 -libcrux_sha3_generic_keccak_new_1e_f4(void) { - libcrux_sha3_generic_keccak_KeccakState_48 lit; - lit.st[0U][0U] = libcrux_sha3_portable_keccak_zero_5a(); - lit.st[0U][1U] = libcrux_sha3_portable_keccak_zero_5a(); - lit.st[0U][2U] = libcrux_sha3_portable_keccak_zero_5a(); - lit.st[0U][3U] = libcrux_sha3_portable_keccak_zero_5a(); - lit.st[0U][4U] = libcrux_sha3_portable_keccak_zero_5a(); - lit.st[1U][0U] = libcrux_sha3_portable_keccak_zero_5a(); - lit.st[1U][1U] = libcrux_sha3_portable_keccak_zero_5a(); - lit.st[1U][2U] = libcrux_sha3_portable_keccak_zero_5a(); - lit.st[1U][3U] = libcrux_sha3_portable_keccak_zero_5a(); - lit.st[1U][4U] = libcrux_sha3_portable_keccak_zero_5a(); - lit.st[2U][0U] = libcrux_sha3_portable_keccak_zero_5a(); - lit.st[2U][1U] = libcrux_sha3_portable_keccak_zero_5a(); - lit.st[2U][2U] = libcrux_sha3_portable_keccak_zero_5a(); - lit.st[2U][3U] = libcrux_sha3_portable_keccak_zero_5a(); - lit.st[2U][4U] = libcrux_sha3_portable_keccak_zero_5a(); - lit.st[3U][0U] = libcrux_sha3_portable_keccak_zero_5a(); - lit.st[3U][1U] = libcrux_sha3_portable_keccak_zero_5a(); - lit.st[3U][2U] = libcrux_sha3_portable_keccak_zero_5a(); - lit.st[3U][3U] = libcrux_sha3_portable_keccak_zero_5a(); - lit.st[3U][4U] = libcrux_sha3_portable_keccak_zero_5a(); - lit.st[4U][0U] = libcrux_sha3_portable_keccak_zero_5a(); - lit.st[4U][1U] = libcrux_sha3_portable_keccak_zero_5a(); - lit.st[4U][2U] = libcrux_sha3_portable_keccak_zero_5a(); - lit.st[4U][3U] = libcrux_sha3_portable_keccak_zero_5a(); - lit.st[4U][4U] = libcrux_sha3_portable_keccak_zero_5a(); - return lit; +static KRML_MUSTINLINE void libcrux_sha3_traits_set_ij_04(uint64_t *arr, + size_t i, size_t j, + uint64_t value) { + arr[(size_t)5U * j + i] = value; } /** -A monomorphic instance of libcrux_sha3.portable_keccak.load_block +A monomorphic instance of libcrux_sha3.simd.portable.load_block with const generics - RATE= 72 */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_2c( - uint64_t (*s)[5U], Eurydice_slice blocks[1U]) { +static KRML_MUSTINLINE void libcrux_sha3_simd_portable_load_block_f8( + uint64_t *state, Eurydice_slice blocks, size_t start) { + uint64_t state_flat[25U] = {0U}; for (size_t i = (size_t)0U; i < (size_t)72U / (size_t)8U; i++) { size_t i0 = i; + size_t offset = start + (size_t)8U * i0; uint8_t uu____0[8U]; - Result_56 dst; + Result_15 dst; Eurydice_slice_to_array2( &dst, - Eurydice_slice_subslice2(blocks[0U], (size_t)8U * i0, - (size_t)8U * i0 + (size_t)8U, uint8_t), - Eurydice_slice, uint8_t[8U]); - unwrap_41_ac(dst, uu____0); - size_t uu____1 = i0 / (size_t)5U; - size_t uu____2 = i0 % (size_t)5U; - s[uu____1][uu____2] = - s[uu____1][uu____2] ^ core_num__u64_9__from_le_bytes(uu____0); + Eurydice_slice_subslice3(blocks, offset, offset + (size_t)8U, + uint8_t *), + Eurydice_slice, uint8_t[8U], TryFromSliceError); + unwrap_26_68(dst, uu____0); + state_flat[i0] = core_num__u64__from_le_bytes(uu____0); + } + for (size_t i = (size_t)0U; i < (size_t)72U / (size_t)8U; i++) { + size_t i0 = i; + libcrux_sha3_traits_set_ij_04( + state, i0 / (size_t)5U, i0 % (size_t)5U, + libcrux_sha3_traits_get_ij_04(state, i0 / (size_t)5U, + i0 % (size_t)5U)[0U] ^ + state_flat[i0]); } } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::Absorb<1usize> for +libcrux_sha3::generic_keccak::KeccakState[core::marker::Sized, +libcrux_sha3::simd::portable::{libcrux_sha3::traits::KeccakItem<1usize> for +u64}]} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.load_block_5a +A monomorphic instance of libcrux_sha3.simd.portable.load_block_a1 with const generics - RATE= 72 */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_5a_b8( - uint64_t (*a)[5U], Eurydice_slice b[1U]) { - uint64_t(*uu____0)[5U] = a; - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_b[1U]; - memcpy(copy_of_b, b, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak_load_block_2c(uu____0, copy_of_b); +static inline void libcrux_sha3_simd_portable_load_block_a1_f8( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice *input, + size_t start) { + libcrux_sha3_simd_portable_load_block_f8(self->st, input[0U], start); +} + +/** +This function found in impl {core::ops::index::Index<(usize, usize), T> for +libcrux_sha3::generic_keccak::KeccakState[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.index_c2 +with types uint64_t +with const generics +- N= 1 +*/ +static inline uint64_t *libcrux_sha3_generic_keccak_index_c2_04( + libcrux_sha3_generic_keccak_KeccakState_17 *self, size_t_x2 index) { + return libcrux_sha3_traits_get_ij_04(self->st, index.fst, index.snd); +} + +/** +This function found in impl {libcrux_sha3::generic_keccak::KeccakState[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.theta_80 +with types uint64_t +with const generics +- N= 1 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_theta_80_04( + libcrux_sha3_generic_keccak_KeccakState_17 *self, uint64_t ret[5U]) { + uint64_t c[5U] = { + libcrux_sha3_simd_portable_xor5_d2( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)0U, + .snd = (size_t)0U}))[0U], + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)1U, + .snd = (size_t)0U}))[0U], + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)2U, + .snd = (size_t)0U}))[0U], + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)3U, + .snd = (size_t)0U}))[0U], + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)4U, + .snd = (size_t)0U}))[0U]), + libcrux_sha3_simd_portable_xor5_d2( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)0U, + .snd = (size_t)1U}))[0U], + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)1U, + .snd = (size_t)1U}))[0U], + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)2U, + .snd = (size_t)1U}))[0U], + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)3U, + .snd = (size_t)1U}))[0U], + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)4U, + .snd = (size_t)1U}))[0U]), + libcrux_sha3_simd_portable_xor5_d2( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)0U, + .snd = (size_t)2U}))[0U], + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)1U, + .snd = (size_t)2U}))[0U], + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)2U, + .snd = (size_t)2U}))[0U], + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)3U, + .snd = (size_t)2U}))[0U], + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)4U, + .snd = (size_t)2U}))[0U]), + libcrux_sha3_simd_portable_xor5_d2( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)0U, + .snd = (size_t)3U}))[0U], + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)1U, + .snd = (size_t)3U}))[0U], + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)2U, + .snd = (size_t)3U}))[0U], + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)3U, + .snd = (size_t)3U}))[0U], + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)4U, + .snd = (size_t)3U}))[0U]), + libcrux_sha3_simd_portable_xor5_d2( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)0U, + .snd = (size_t)4U}))[0U], + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)1U, + .snd = (size_t)4U}))[0U], + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)2U, + .snd = (size_t)4U}))[0U], + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)3U, + .snd = (size_t)4U}))[0U], + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)4U, + .snd = (size_t)4U}))[0U])}; + uint64_t uu____0 = libcrux_sha3_simd_portable_rotate_left1_and_xor_d2( + c[((size_t)0U + (size_t)4U) % (size_t)5U], + c[((size_t)0U + (size_t)1U) % (size_t)5U]); + uint64_t uu____1 = libcrux_sha3_simd_portable_rotate_left1_and_xor_d2( + c[((size_t)1U + (size_t)4U) % (size_t)5U], + c[((size_t)1U + (size_t)1U) % (size_t)5U]); + uint64_t uu____2 = libcrux_sha3_simd_portable_rotate_left1_and_xor_d2( + c[((size_t)2U + (size_t)4U) % (size_t)5U], + c[((size_t)2U + (size_t)1U) % (size_t)5U]); + uint64_t uu____3 = libcrux_sha3_simd_portable_rotate_left1_and_xor_d2( + c[((size_t)3U + (size_t)4U) % (size_t)5U], + c[((size_t)3U + (size_t)1U) % (size_t)5U]); + ret[0U] = uu____0; + ret[1U] = uu____1; + ret[2U] = uu____2; + ret[3U] = uu____3; + ret[4U] = libcrux_sha3_simd_portable_rotate_left1_and_xor_d2( + c[((size_t)4U + (size_t)4U) % (size_t)5U], + c[((size_t)4U + (size_t)1U) % (size_t)5U]); +} + +/** +This function found in impl {libcrux_sha3::generic_keccak::KeccakState[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.set_80 +with types uint64_t +with const generics +- N= 1 +*/ +static inline void libcrux_sha3_generic_keccak_set_80_04( + libcrux_sha3_generic_keccak_KeccakState_17 *self, size_t i, size_t j, + uint64_t v) { + libcrux_sha3_traits_set_ij_04(self->st, i, j, v); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +A monomorphic instance of libcrux_sha3.simd.portable.rotate_left with const generics - LEFT= 36 - RIGHT= 28 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_rotate_left_cb0(uint64_t x) { - return x << (uint32_t)(int32_t)36 | x >> (uint32_t)(int32_t)28; +libcrux_sha3_simd_portable_rotate_left_02(uint64_t x) { + return core_num__u64__rotate_left(x, (uint32_t)(int32_t)36); } /** -A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +A monomorphic instance of libcrux_sha3.simd.portable._vxarq_u64 with const generics - LEFT= 36 - RIGHT= 28 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak__vxarq_u64_42(uint64_t a, uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left_cb0(ab); +libcrux_sha3_simd_portable__vxarq_u64_02(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable_rotate_left_02(a ^ b); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +A monomorphic instance of libcrux_sha3.simd.portable.xor_and_rotate_d2 with const generics - LEFT= 36 - RIGHT= 28 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb(uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64_42(a, b); +libcrux_sha3_simd_portable_xor_and_rotate_d2_02(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable__vxarq_u64_02(a, b); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +A monomorphic instance of libcrux_sha3.simd.portable.rotate_left with const generics - LEFT= 3 - RIGHT= 61 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_rotate_left_cb1(uint64_t x) { - return x << (uint32_t)(int32_t)3 | x >> (uint32_t)(int32_t)61; +libcrux_sha3_simd_portable_rotate_left_ac(uint64_t x) { + return core_num__u64__rotate_left(x, (uint32_t)(int32_t)3); } /** -A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +A monomorphic instance of libcrux_sha3.simd.portable._vxarq_u64 with const generics - LEFT= 3 - RIGHT= 61 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak__vxarq_u64_420(uint64_t a, uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left_cb1(ab); +libcrux_sha3_simd_portable__vxarq_u64_ac(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable_rotate_left_ac(a ^ b); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +A monomorphic instance of libcrux_sha3.simd.portable.xor_and_rotate_d2 with const generics - LEFT= 3 - RIGHT= 61 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb0(uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64_420(a, b); +libcrux_sha3_simd_portable_xor_and_rotate_d2_ac(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable__vxarq_u64_ac(a, b); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +A monomorphic instance of libcrux_sha3.simd.portable.rotate_left with const generics - LEFT= 41 - RIGHT= 23 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_rotate_left_cb2(uint64_t x) { - return x << (uint32_t)(int32_t)41 | x >> (uint32_t)(int32_t)23; +libcrux_sha3_simd_portable_rotate_left_020(uint64_t x) { + return core_num__u64__rotate_left(x, (uint32_t)(int32_t)41); } /** -A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +A monomorphic instance of libcrux_sha3.simd.portable._vxarq_u64 with const generics - LEFT= 41 - RIGHT= 23 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak__vxarq_u64_421(uint64_t a, uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left_cb2(ab); +libcrux_sha3_simd_portable__vxarq_u64_020(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable_rotate_left_020(a ^ b); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +A monomorphic instance of libcrux_sha3.simd.portable.xor_and_rotate_d2 with const generics - LEFT= 41 - RIGHT= 23 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb1(uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64_421(a, b); +libcrux_sha3_simd_portable_xor_and_rotate_d2_020(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable__vxarq_u64_020(a, b); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +A monomorphic instance of libcrux_sha3.simd.portable.rotate_left with const generics - LEFT= 18 - RIGHT= 46 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_rotate_left_cb3(uint64_t x) { - return x << (uint32_t)(int32_t)18 | x >> (uint32_t)(int32_t)46; +libcrux_sha3_simd_portable_rotate_left_a9(uint64_t x) { + return core_num__u64__rotate_left(x, (uint32_t)(int32_t)18); } /** -A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +A monomorphic instance of libcrux_sha3.simd.portable._vxarq_u64 with const generics - LEFT= 18 - RIGHT= 46 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak__vxarq_u64_422(uint64_t a, uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left_cb3(ab); +libcrux_sha3_simd_portable__vxarq_u64_a9(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable_rotate_left_a9(a ^ b); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +A monomorphic instance of libcrux_sha3.simd.portable.xor_and_rotate_d2 with const generics - LEFT= 18 - RIGHT= 46 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb2(uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64_422(a, b); +libcrux_sha3_simd_portable_xor_and_rotate_d2_a9(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable__vxarq_u64_a9(a, b); } /** -A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +A monomorphic instance of libcrux_sha3.simd.portable._vxarq_u64 with const generics - LEFT= 1 - RIGHT= 63 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak__vxarq_u64_423(uint64_t a, uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left_cb(ab); +libcrux_sha3_simd_portable__vxarq_u64_76(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable_rotate_left_76(a ^ b); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +A monomorphic instance of libcrux_sha3.simd.portable.xor_and_rotate_d2 with const generics - LEFT= 1 - RIGHT= 63 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb3(uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64_423(a, b); +libcrux_sha3_simd_portable_xor_and_rotate_d2_76(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable__vxarq_u64_76(a, b); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +A monomorphic instance of libcrux_sha3.simd.portable.rotate_left with const generics - LEFT= 44 - RIGHT= 20 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_rotate_left_cb4(uint64_t x) { - return x << (uint32_t)(int32_t)44 | x >> (uint32_t)(int32_t)20; +libcrux_sha3_simd_portable_rotate_left_58(uint64_t x) { + return core_num__u64__rotate_left(x, (uint32_t)(int32_t)44); } /** -A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +A monomorphic instance of libcrux_sha3.simd.portable._vxarq_u64 with const generics - LEFT= 44 - RIGHT= 20 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak__vxarq_u64_424(uint64_t a, uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left_cb4(ab); +libcrux_sha3_simd_portable__vxarq_u64_58(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable_rotate_left_58(a ^ b); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +A monomorphic instance of libcrux_sha3.simd.portable.xor_and_rotate_d2 with const generics - LEFT= 44 - RIGHT= 20 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb4(uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64_424(a, b); +libcrux_sha3_simd_portable_xor_and_rotate_d2_58(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable__vxarq_u64_58(a, b); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +A monomorphic instance of libcrux_sha3.simd.portable.rotate_left with const generics - LEFT= 10 - RIGHT= 54 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_rotate_left_cb5(uint64_t x) { - return x << (uint32_t)(int32_t)10 | x >> (uint32_t)(int32_t)54; +libcrux_sha3_simd_portable_rotate_left_e0(uint64_t x) { + return core_num__u64__rotate_left(x, (uint32_t)(int32_t)10); } /** -A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +A monomorphic instance of libcrux_sha3.simd.portable._vxarq_u64 with const generics - LEFT= 10 - RIGHT= 54 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak__vxarq_u64_425(uint64_t a, uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left_cb5(ab); +libcrux_sha3_simd_portable__vxarq_u64_e0(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable_rotate_left_e0(a ^ b); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +A monomorphic instance of libcrux_sha3.simd.portable.xor_and_rotate_d2 with const generics - LEFT= 10 - RIGHT= 54 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb5(uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64_425(a, b); +libcrux_sha3_simd_portable_xor_and_rotate_d2_e0(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable__vxarq_u64_e0(a, b); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +A monomorphic instance of libcrux_sha3.simd.portable.rotate_left with const generics - LEFT= 45 - RIGHT= 19 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_rotate_left_cb6(uint64_t x) { - return x << (uint32_t)(int32_t)45 | x >> (uint32_t)(int32_t)19; +libcrux_sha3_simd_portable_rotate_left_63(uint64_t x) { + return core_num__u64__rotate_left(x, (uint32_t)(int32_t)45); } /** -A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +A monomorphic instance of libcrux_sha3.simd.portable._vxarq_u64 with const generics - LEFT= 45 - RIGHT= 19 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak__vxarq_u64_426(uint64_t a, uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left_cb6(ab); +libcrux_sha3_simd_portable__vxarq_u64_63(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable_rotate_left_63(a ^ b); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +A monomorphic instance of libcrux_sha3.simd.portable.xor_and_rotate_d2 with const generics - LEFT= 45 - RIGHT= 19 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb6(uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64_426(a, b); +libcrux_sha3_simd_portable_xor_and_rotate_d2_63(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable__vxarq_u64_63(a, b); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +A monomorphic instance of libcrux_sha3.simd.portable.rotate_left with const generics - LEFT= 2 - RIGHT= 62 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_rotate_left_cb7(uint64_t x) { - return x << (uint32_t)(int32_t)2 | x >> (uint32_t)(int32_t)62; +libcrux_sha3_simd_portable_rotate_left_6a(uint64_t x) { + return core_num__u64__rotate_left(x, (uint32_t)(int32_t)2); } /** -A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +A monomorphic instance of libcrux_sha3.simd.portable._vxarq_u64 with const generics - LEFT= 2 - RIGHT= 62 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak__vxarq_u64_427(uint64_t a, uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left_cb7(ab); +libcrux_sha3_simd_portable__vxarq_u64_6a(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable_rotate_left_6a(a ^ b); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +A monomorphic instance of libcrux_sha3.simd.portable.xor_and_rotate_d2 with const generics - LEFT= 2 - RIGHT= 62 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb7(uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64_427(a, b); +libcrux_sha3_simd_portable_xor_and_rotate_d2_6a(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable__vxarq_u64_6a(a, b); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +A monomorphic instance of libcrux_sha3.simd.portable.rotate_left with const generics - LEFT= 62 - RIGHT= 2 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_rotate_left_cb8(uint64_t x) { - return x << (uint32_t)(int32_t)62 | x >> (uint32_t)(int32_t)2; +libcrux_sha3_simd_portable_rotate_left_ab(uint64_t x) { + return core_num__u64__rotate_left(x, (uint32_t)(int32_t)62); } /** -A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +A monomorphic instance of libcrux_sha3.simd.portable._vxarq_u64 with const generics - LEFT= 62 - RIGHT= 2 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak__vxarq_u64_428(uint64_t a, uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left_cb8(ab); +libcrux_sha3_simd_portable__vxarq_u64_ab(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable_rotate_left_ab(a ^ b); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +A monomorphic instance of libcrux_sha3.simd.portable.xor_and_rotate_d2 with const generics - LEFT= 62 - RIGHT= 2 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb8(uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64_428(a, b); +libcrux_sha3_simd_portable_xor_and_rotate_d2_ab(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable__vxarq_u64_ab(a, b); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +A monomorphic instance of libcrux_sha3.simd.portable.rotate_left with const generics - LEFT= 6 - RIGHT= 58 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_rotate_left_cb9(uint64_t x) { - return x << (uint32_t)(int32_t)6 | x >> (uint32_t)(int32_t)58; +libcrux_sha3_simd_portable_rotate_left_5b(uint64_t x) { + return core_num__u64__rotate_left(x, (uint32_t)(int32_t)6); } /** -A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +A monomorphic instance of libcrux_sha3.simd.portable._vxarq_u64 with const generics - LEFT= 6 - RIGHT= 58 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak__vxarq_u64_429(uint64_t a, uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left_cb9(ab); +libcrux_sha3_simd_portable__vxarq_u64_5b(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable_rotate_left_5b(a ^ b); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +A monomorphic instance of libcrux_sha3.simd.portable.xor_and_rotate_d2 with const generics - LEFT= 6 - RIGHT= 58 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb9(uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64_429(a, b); +libcrux_sha3_simd_portable_xor_and_rotate_d2_5b(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable__vxarq_u64_5b(a, b); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +A monomorphic instance of libcrux_sha3.simd.portable.rotate_left with const generics - LEFT= 43 - RIGHT= 21 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_rotate_left_cb10(uint64_t x) { - return x << (uint32_t)(int32_t)43 | x >> (uint32_t)(int32_t)21; +libcrux_sha3_simd_portable_rotate_left_6f(uint64_t x) { + return core_num__u64__rotate_left(x, (uint32_t)(int32_t)43); } /** -A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +A monomorphic instance of libcrux_sha3.simd.portable._vxarq_u64 with const generics - LEFT= 43 - RIGHT= 21 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak__vxarq_u64_4210(uint64_t a, uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left_cb10(ab); +libcrux_sha3_simd_portable__vxarq_u64_6f(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable_rotate_left_6f(a ^ b); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +A monomorphic instance of libcrux_sha3.simd.portable.xor_and_rotate_d2 with const generics - LEFT= 43 - RIGHT= 21 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb10(uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64_4210(a, b); +libcrux_sha3_simd_portable_xor_and_rotate_d2_6f(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable__vxarq_u64_6f(a, b); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +A monomorphic instance of libcrux_sha3.simd.portable.rotate_left with const generics - LEFT= 15 - RIGHT= 49 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_rotate_left_cb11(uint64_t x) { - return x << (uint32_t)(int32_t)15 | x >> (uint32_t)(int32_t)49; +libcrux_sha3_simd_portable_rotate_left_62(uint64_t x) { + return core_num__u64__rotate_left(x, (uint32_t)(int32_t)15); } /** -A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +A monomorphic instance of libcrux_sha3.simd.portable._vxarq_u64 with const generics - LEFT= 15 - RIGHT= 49 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak__vxarq_u64_4211(uint64_t a, uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left_cb11(ab); +libcrux_sha3_simd_portable__vxarq_u64_62(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable_rotate_left_62(a ^ b); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +A monomorphic instance of libcrux_sha3.simd.portable.xor_and_rotate_d2 with const generics - LEFT= 15 - RIGHT= 49 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb11(uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64_4211(a, b); +libcrux_sha3_simd_portable_xor_and_rotate_d2_62(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable__vxarq_u64_62(a, b); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +A monomorphic instance of libcrux_sha3.simd.portable.rotate_left with const generics - LEFT= 61 - RIGHT= 3 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_rotate_left_cb12(uint64_t x) { - return x << (uint32_t)(int32_t)61 | x >> (uint32_t)(int32_t)3; +libcrux_sha3_simd_portable_rotate_left_23(uint64_t x) { + return core_num__u64__rotate_left(x, (uint32_t)(int32_t)61); } /** -A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +A monomorphic instance of libcrux_sha3.simd.portable._vxarq_u64 with const generics - LEFT= 61 - RIGHT= 3 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak__vxarq_u64_4212(uint64_t a, uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left_cb12(ab); +libcrux_sha3_simd_portable__vxarq_u64_23(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable_rotate_left_23(a ^ b); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +A monomorphic instance of libcrux_sha3.simd.portable.xor_and_rotate_d2 with const generics - LEFT= 61 - RIGHT= 3 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb12(uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64_4212(a, b); +libcrux_sha3_simd_portable_xor_and_rotate_d2_23(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable__vxarq_u64_23(a, b); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +A monomorphic instance of libcrux_sha3.simd.portable.rotate_left with const generics - LEFT= 28 - RIGHT= 36 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_rotate_left_cb13(uint64_t x) { - return x << (uint32_t)(int32_t)28 | x >> (uint32_t)(int32_t)36; +libcrux_sha3_simd_portable_rotate_left_37(uint64_t x) { + return core_num__u64__rotate_left(x, (uint32_t)(int32_t)28); } /** -A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +A monomorphic instance of libcrux_sha3.simd.portable._vxarq_u64 with const generics - LEFT= 28 - RIGHT= 36 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak__vxarq_u64_4213(uint64_t a, uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left_cb13(ab); +libcrux_sha3_simd_portable__vxarq_u64_37(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable_rotate_left_37(a ^ b); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +A monomorphic instance of libcrux_sha3.simd.portable.xor_and_rotate_d2 with const generics - LEFT= 28 - RIGHT= 36 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb13(uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64_4213(a, b); +libcrux_sha3_simd_portable_xor_and_rotate_d2_37(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable__vxarq_u64_37(a, b); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +A monomorphic instance of libcrux_sha3.simd.portable.rotate_left with const generics - LEFT= 55 - RIGHT= 9 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_rotate_left_cb14(uint64_t x) { - return x << (uint32_t)(int32_t)55 | x >> (uint32_t)(int32_t)9; +libcrux_sha3_simd_portable_rotate_left_bb(uint64_t x) { + return core_num__u64__rotate_left(x, (uint32_t)(int32_t)55); } /** -A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +A monomorphic instance of libcrux_sha3.simd.portable._vxarq_u64 with const generics - LEFT= 55 - RIGHT= 9 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak__vxarq_u64_4214(uint64_t a, uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left_cb14(ab); +libcrux_sha3_simd_portable__vxarq_u64_bb(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable_rotate_left_bb(a ^ b); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +A monomorphic instance of libcrux_sha3.simd.portable.xor_and_rotate_d2 with const generics - LEFT= 55 - RIGHT= 9 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb14(uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64_4214(a, b); +libcrux_sha3_simd_portable_xor_and_rotate_d2_bb(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable__vxarq_u64_bb(a, b); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +A monomorphic instance of libcrux_sha3.simd.portable.rotate_left with const generics - LEFT= 25 - RIGHT= 39 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_rotate_left_cb15(uint64_t x) { - return x << (uint32_t)(int32_t)25 | x >> (uint32_t)(int32_t)39; +libcrux_sha3_simd_portable_rotate_left_b9(uint64_t x) { + return core_num__u64__rotate_left(x, (uint32_t)(int32_t)25); } /** -A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +A monomorphic instance of libcrux_sha3.simd.portable._vxarq_u64 with const generics - LEFT= 25 - RIGHT= 39 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak__vxarq_u64_4215(uint64_t a, uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left_cb15(ab); +libcrux_sha3_simd_portable__vxarq_u64_b9(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable_rotate_left_b9(a ^ b); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +A monomorphic instance of libcrux_sha3.simd.portable.xor_and_rotate_d2 with const generics - LEFT= 25 - RIGHT= 39 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb15(uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64_4215(a, b); +libcrux_sha3_simd_portable_xor_and_rotate_d2_b9(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable__vxarq_u64_b9(a, b); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +A monomorphic instance of libcrux_sha3.simd.portable.rotate_left with const generics - LEFT= 21 - RIGHT= 43 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_rotate_left_cb16(uint64_t x) { - return x << (uint32_t)(int32_t)21 | x >> (uint32_t)(int32_t)43; +libcrux_sha3_simd_portable_rotate_left_54(uint64_t x) { + return core_num__u64__rotate_left(x, (uint32_t)(int32_t)21); } /** -A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +A monomorphic instance of libcrux_sha3.simd.portable._vxarq_u64 with const generics - LEFT= 21 - RIGHT= 43 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak__vxarq_u64_4216(uint64_t a, uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left_cb16(ab); +libcrux_sha3_simd_portable__vxarq_u64_54(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable_rotate_left_54(a ^ b); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +A monomorphic instance of libcrux_sha3.simd.portable.xor_and_rotate_d2 with const generics - LEFT= 21 - RIGHT= 43 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb16(uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64_4216(a, b); +libcrux_sha3_simd_portable_xor_and_rotate_d2_54(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable__vxarq_u64_54(a, b); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +A monomorphic instance of libcrux_sha3.simd.portable.rotate_left with const generics - LEFT= 56 - RIGHT= 8 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_rotate_left_cb17(uint64_t x) { - return x << (uint32_t)(int32_t)56 | x >> (uint32_t)(int32_t)8; +libcrux_sha3_simd_portable_rotate_left_4c(uint64_t x) { + return core_num__u64__rotate_left(x, (uint32_t)(int32_t)56); } /** -A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +A monomorphic instance of libcrux_sha3.simd.portable._vxarq_u64 with const generics - LEFT= 56 - RIGHT= 8 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak__vxarq_u64_4217(uint64_t a, uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left_cb17(ab); +libcrux_sha3_simd_portable__vxarq_u64_4c(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable_rotate_left_4c(a ^ b); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +A monomorphic instance of libcrux_sha3.simd.portable.xor_and_rotate_d2 with const generics - LEFT= 56 - RIGHT= 8 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb17(uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64_4217(a, b); +libcrux_sha3_simd_portable_xor_and_rotate_d2_4c(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable__vxarq_u64_4c(a, b); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +A monomorphic instance of libcrux_sha3.simd.portable.rotate_left with const generics - LEFT= 27 - RIGHT= 37 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_rotate_left_cb18(uint64_t x) { - return x << (uint32_t)(int32_t)27 | x >> (uint32_t)(int32_t)37; +libcrux_sha3_simd_portable_rotate_left_ce(uint64_t x) { + return core_num__u64__rotate_left(x, (uint32_t)(int32_t)27); } /** -A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +A monomorphic instance of libcrux_sha3.simd.portable._vxarq_u64 with const generics - LEFT= 27 - RIGHT= 37 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak__vxarq_u64_4218(uint64_t a, uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left_cb18(ab); +libcrux_sha3_simd_portable__vxarq_u64_ce(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable_rotate_left_ce(a ^ b); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +A monomorphic instance of libcrux_sha3.simd.portable.xor_and_rotate_d2 with const generics - LEFT= 27 - RIGHT= 37 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb18(uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64_4218(a, b); +libcrux_sha3_simd_portable_xor_and_rotate_d2_ce(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable__vxarq_u64_ce(a, b); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +A monomorphic instance of libcrux_sha3.simd.portable.rotate_left with const generics - LEFT= 20 - RIGHT= 44 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_rotate_left_cb19(uint64_t x) { - return x << (uint32_t)(int32_t)20 | x >> (uint32_t)(int32_t)44; +libcrux_sha3_simd_portable_rotate_left_77(uint64_t x) { + return core_num__u64__rotate_left(x, (uint32_t)(int32_t)20); } /** -A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +A monomorphic instance of libcrux_sha3.simd.portable._vxarq_u64 with const generics - LEFT= 20 - RIGHT= 44 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak__vxarq_u64_4219(uint64_t a, uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left_cb19(ab); +libcrux_sha3_simd_portable__vxarq_u64_77(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable_rotate_left_77(a ^ b); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +A monomorphic instance of libcrux_sha3.simd.portable.xor_and_rotate_d2 with const generics - LEFT= 20 - RIGHT= 44 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb19(uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64_4219(a, b); +libcrux_sha3_simd_portable_xor_and_rotate_d2_77(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable__vxarq_u64_77(a, b); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +A monomorphic instance of libcrux_sha3.simd.portable.rotate_left with const generics - LEFT= 39 - RIGHT= 25 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_rotate_left_cb20(uint64_t x) { - return x << (uint32_t)(int32_t)39 | x >> (uint32_t)(int32_t)25; +libcrux_sha3_simd_portable_rotate_left_25(uint64_t x) { + return core_num__u64__rotate_left(x, (uint32_t)(int32_t)39); } /** -A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +A monomorphic instance of libcrux_sha3.simd.portable._vxarq_u64 with const generics - LEFT= 39 - RIGHT= 25 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak__vxarq_u64_4220(uint64_t a, uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left_cb20(ab); +libcrux_sha3_simd_portable__vxarq_u64_25(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable_rotate_left_25(a ^ b); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +A monomorphic instance of libcrux_sha3.simd.portable.xor_and_rotate_d2 with const generics - LEFT= 39 - RIGHT= 25 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb20(uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64_4220(a, b); +libcrux_sha3_simd_portable_xor_and_rotate_d2_25(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable__vxarq_u64_25(a, b); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +A monomorphic instance of libcrux_sha3.simd.portable.rotate_left with const generics - LEFT= 8 - RIGHT= 56 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_rotate_left_cb21(uint64_t x) { - return x << (uint32_t)(int32_t)8 | x >> (uint32_t)(int32_t)56; +libcrux_sha3_simd_portable_rotate_left_af(uint64_t x) { + return core_num__u64__rotate_left(x, (uint32_t)(int32_t)8); } /** -A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +A monomorphic instance of libcrux_sha3.simd.portable._vxarq_u64 with const generics - LEFT= 8 - RIGHT= 56 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak__vxarq_u64_4221(uint64_t a, uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left_cb21(ab); +libcrux_sha3_simd_portable__vxarq_u64_af(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable_rotate_left_af(a ^ b); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +A monomorphic instance of libcrux_sha3.simd.portable.xor_and_rotate_d2 with const generics - LEFT= 8 - RIGHT= 56 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb21(uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64_4221(a, b); +libcrux_sha3_simd_portable_xor_and_rotate_d2_af(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable__vxarq_u64_af(a, b); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +A monomorphic instance of libcrux_sha3.simd.portable.rotate_left with const generics - LEFT= 14 - RIGHT= 50 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_rotate_left_cb22(uint64_t x) { - return x << (uint32_t)(int32_t)14 | x >> (uint32_t)(int32_t)50; +libcrux_sha3_simd_portable_rotate_left_fd(uint64_t x) { + return core_num__u64__rotate_left(x, (uint32_t)(int32_t)14); } /** -A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +A monomorphic instance of libcrux_sha3.simd.portable._vxarq_u64 with const generics - LEFT= 14 - RIGHT= 50 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak__vxarq_u64_4222(uint64_t a, uint64_t b) { - uint64_t ab = a ^ b; - return libcrux_sha3_portable_keccak_rotate_left_cb22(ab); +libcrux_sha3_simd_portable__vxarq_u64_fd(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable_rotate_left_fd(a ^ b); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::KeccakItem<1usize> for u64} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +A monomorphic instance of libcrux_sha3.simd.portable.xor_and_rotate_d2 with const generics - LEFT= 14 - RIGHT= 50 */ static KRML_MUSTINLINE uint64_t -libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb22(uint64_t a, uint64_t b) { - return libcrux_sha3_portable_keccak__vxarq_u64_4222(a, b); +libcrux_sha3_simd_portable_xor_and_rotate_d2_fd(uint64_t a, uint64_t b) { + return libcrux_sha3_simd_portable__vxarq_u64_fd(a, b); } /** -A monomorphic instance of libcrux_sha3.generic_keccak.theta_rho +This function found in impl {libcrux_sha3::generic_keccak::KeccakState[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.rho_80 with types uint64_t with const generics - N= 1 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_theta_rho_16( - libcrux_sha3_generic_keccak_KeccakState_48 *s) { - uint64_t c[5U] = { - libcrux_sha3_portable_keccak_xor5_5a(s->st[0U][0U], s->st[1U][0U], - s->st[2U][0U], s->st[3U][0U], - s->st[4U][0U]), - libcrux_sha3_portable_keccak_xor5_5a(s->st[0U][1U], s->st[1U][1U], - s->st[2U][1U], s->st[3U][1U], - s->st[4U][1U]), - libcrux_sha3_portable_keccak_xor5_5a(s->st[0U][2U], s->st[1U][2U], - s->st[2U][2U], s->st[3U][2U], - s->st[4U][2U]), - libcrux_sha3_portable_keccak_xor5_5a(s->st[0U][3U], s->st[1U][3U], - s->st[2U][3U], s->st[3U][3U], - s->st[4U][3U]), - libcrux_sha3_portable_keccak_xor5_5a(s->st[0U][4U], s->st[1U][4U], - s->st[2U][4U], s->st[3U][4U], - s->st[4U][4U])}; - uint64_t uu____0 = libcrux_sha3_portable_keccak_rotate_left1_and_xor_5a( - c[((size_t)0U + (size_t)4U) % (size_t)5U], - c[((size_t)0U + (size_t)1U) % (size_t)5U]); - uint64_t uu____1 = libcrux_sha3_portable_keccak_rotate_left1_and_xor_5a( - c[((size_t)1U + (size_t)4U) % (size_t)5U], - c[((size_t)1U + (size_t)1U) % (size_t)5U]); - uint64_t uu____2 = libcrux_sha3_portable_keccak_rotate_left1_and_xor_5a( - c[((size_t)2U + (size_t)4U) % (size_t)5U], - c[((size_t)2U + (size_t)1U) % (size_t)5U]); - uint64_t uu____3 = libcrux_sha3_portable_keccak_rotate_left1_and_xor_5a( - c[((size_t)3U + (size_t)4U) % (size_t)5U], - c[((size_t)3U + (size_t)1U) % (size_t)5U]); - uint64_t t[5U] = {uu____0, uu____1, uu____2, uu____3, - libcrux_sha3_portable_keccak_rotate_left1_and_xor_5a( - c[((size_t)4U + (size_t)4U) % (size_t)5U], - c[((size_t)4U + (size_t)1U) % (size_t)5U])}; - s->st[0U][0U] = libcrux_sha3_portable_keccak_xor_5a(s->st[0U][0U], t[0U]); - s->st[1U][0U] = - libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb(s->st[1U][0U], t[0U]); - s->st[2U][0U] = - libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb0(s->st[2U][0U], t[0U]); - s->st[3U][0U] = - libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb1(s->st[3U][0U], t[0U]); - s->st[4U][0U] = - libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb2(s->st[4U][0U], t[0U]); - s->st[0U][1U] = - libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb3(s->st[0U][1U], t[1U]); - s->st[1U][1U] = - libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb4(s->st[1U][1U], t[1U]); - s->st[2U][1U] = - libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb5(s->st[2U][1U], t[1U]); - s->st[3U][1U] = - libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb6(s->st[3U][1U], t[1U]); - s->st[4U][1U] = - libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb7(s->st[4U][1U], t[1U]); - s->st[0U][2U] = - libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb8(s->st[0U][2U], t[2U]); - s->st[1U][2U] = - libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb9(s->st[1U][2U], t[2U]); - s->st[2U][2U] = - libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb10(s->st[2U][2U], t[2U]); - s->st[3U][2U] = - libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb11(s->st[3U][2U], t[2U]); - s->st[4U][2U] = - libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb12(s->st[4U][2U], t[2U]); - s->st[0U][3U] = - libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb13(s->st[0U][3U], t[3U]); - s->st[1U][3U] = - libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb14(s->st[1U][3U], t[3U]); - s->st[2U][3U] = - libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb15(s->st[2U][3U], t[3U]); - s->st[3U][3U] = - libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb16(s->st[3U][3U], t[3U]); - s->st[4U][3U] = - libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb17(s->st[4U][3U], t[3U]); - s->st[0U][4U] = - libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb18(s->st[0U][4U], t[4U]); - s->st[1U][4U] = - libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb19(s->st[1U][4U], t[4U]); - s->st[2U][4U] = - libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb20(s->st[2U][4U], t[4U]); - s->st[3U][4U] = - libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb21(s->st[3U][4U], t[4U]); - uint64_t uu____27 = - libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb22(s->st[4U][4U], t[4U]); - s->st[4U][4U] = uu____27; -} - -/** -A monomorphic instance of libcrux_sha3.generic_keccak.pi +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_rho_80_04( + libcrux_sha3_generic_keccak_KeccakState_17 *self, uint64_t t[5U]) { + libcrux_sha3_generic_keccak_set_80_04( + self, (size_t)0U, (size_t)0U, + libcrux_sha3_simd_portable_xor_d2( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)0U, + .snd = (size_t)0U}))[0U], + t[0U])); + libcrux_sha3_generic_keccak_KeccakState_17 *uu____0 = self; + libcrux_sha3_generic_keccak_set_80_04( + uu____0, (size_t)1U, (size_t)0U, + libcrux_sha3_simd_portable_xor_and_rotate_d2_02( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)1U, + .snd = (size_t)0U}))[0U], + t[0U])); + libcrux_sha3_generic_keccak_KeccakState_17 *uu____1 = self; + libcrux_sha3_generic_keccak_set_80_04( + uu____1, (size_t)2U, (size_t)0U, + libcrux_sha3_simd_portable_xor_and_rotate_d2_ac( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)2U, + .snd = (size_t)0U}))[0U], + t[0U])); + libcrux_sha3_generic_keccak_KeccakState_17 *uu____2 = self; + libcrux_sha3_generic_keccak_set_80_04( + uu____2, (size_t)3U, (size_t)0U, + libcrux_sha3_simd_portable_xor_and_rotate_d2_020( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)3U, + .snd = (size_t)0U}))[0U], + t[0U])); + libcrux_sha3_generic_keccak_KeccakState_17 *uu____3 = self; + libcrux_sha3_generic_keccak_set_80_04( + uu____3, (size_t)4U, (size_t)0U, + libcrux_sha3_simd_portable_xor_and_rotate_d2_a9( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)4U, + .snd = (size_t)0U}))[0U], + t[0U])); + libcrux_sha3_generic_keccak_KeccakState_17 *uu____4 = self; + libcrux_sha3_generic_keccak_set_80_04( + uu____4, (size_t)0U, (size_t)1U, + libcrux_sha3_simd_portable_xor_and_rotate_d2_76( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)0U, + .snd = (size_t)1U}))[0U], + t[1U])); + libcrux_sha3_generic_keccak_KeccakState_17 *uu____5 = self; + libcrux_sha3_generic_keccak_set_80_04( + uu____5, (size_t)1U, (size_t)1U, + libcrux_sha3_simd_portable_xor_and_rotate_d2_58( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)1U, + .snd = (size_t)1U}))[0U], + t[1U])); + libcrux_sha3_generic_keccak_KeccakState_17 *uu____6 = self; + libcrux_sha3_generic_keccak_set_80_04( + uu____6, (size_t)2U, (size_t)1U, + libcrux_sha3_simd_portable_xor_and_rotate_d2_e0( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)2U, + .snd = (size_t)1U}))[0U], + t[1U])); + libcrux_sha3_generic_keccak_KeccakState_17 *uu____7 = self; + libcrux_sha3_generic_keccak_set_80_04( + uu____7, (size_t)3U, (size_t)1U, + libcrux_sha3_simd_portable_xor_and_rotate_d2_63( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)3U, + .snd = (size_t)1U}))[0U], + t[1U])); + libcrux_sha3_generic_keccak_KeccakState_17 *uu____8 = self; + libcrux_sha3_generic_keccak_set_80_04( + uu____8, (size_t)4U, (size_t)1U, + libcrux_sha3_simd_portable_xor_and_rotate_d2_6a( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)4U, + .snd = (size_t)1U}))[0U], + t[1U])); + libcrux_sha3_generic_keccak_KeccakState_17 *uu____9 = self; + libcrux_sha3_generic_keccak_set_80_04( + uu____9, (size_t)0U, (size_t)2U, + libcrux_sha3_simd_portable_xor_and_rotate_d2_ab( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)0U, + .snd = (size_t)2U}))[0U], + t[2U])); + libcrux_sha3_generic_keccak_KeccakState_17 *uu____10 = self; + libcrux_sha3_generic_keccak_set_80_04( + uu____10, (size_t)1U, (size_t)2U, + libcrux_sha3_simd_portable_xor_and_rotate_d2_5b( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)1U, + .snd = (size_t)2U}))[0U], + t[2U])); + libcrux_sha3_generic_keccak_KeccakState_17 *uu____11 = self; + libcrux_sha3_generic_keccak_set_80_04( + uu____11, (size_t)2U, (size_t)2U, + libcrux_sha3_simd_portable_xor_and_rotate_d2_6f( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)2U, + .snd = (size_t)2U}))[0U], + t[2U])); + libcrux_sha3_generic_keccak_KeccakState_17 *uu____12 = self; + libcrux_sha3_generic_keccak_set_80_04( + uu____12, (size_t)3U, (size_t)2U, + libcrux_sha3_simd_portable_xor_and_rotate_d2_62( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)3U, + .snd = (size_t)2U}))[0U], + t[2U])); + libcrux_sha3_generic_keccak_KeccakState_17 *uu____13 = self; + libcrux_sha3_generic_keccak_set_80_04( + uu____13, (size_t)4U, (size_t)2U, + libcrux_sha3_simd_portable_xor_and_rotate_d2_23( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)4U, + .snd = (size_t)2U}))[0U], + t[2U])); + libcrux_sha3_generic_keccak_KeccakState_17 *uu____14 = self; + libcrux_sha3_generic_keccak_set_80_04( + uu____14, (size_t)0U, (size_t)3U, + libcrux_sha3_simd_portable_xor_and_rotate_d2_37( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)0U, + .snd = (size_t)3U}))[0U], + t[3U])); + libcrux_sha3_generic_keccak_KeccakState_17 *uu____15 = self; + libcrux_sha3_generic_keccak_set_80_04( + uu____15, (size_t)1U, (size_t)3U, + libcrux_sha3_simd_portable_xor_and_rotate_d2_bb( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)1U, + .snd = (size_t)3U}))[0U], + t[3U])); + libcrux_sha3_generic_keccak_KeccakState_17 *uu____16 = self; + libcrux_sha3_generic_keccak_set_80_04( + uu____16, (size_t)2U, (size_t)3U, + libcrux_sha3_simd_portable_xor_and_rotate_d2_b9( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)2U, + .snd = (size_t)3U}))[0U], + t[3U])); + libcrux_sha3_generic_keccak_KeccakState_17 *uu____17 = self; + libcrux_sha3_generic_keccak_set_80_04( + uu____17, (size_t)3U, (size_t)3U, + libcrux_sha3_simd_portable_xor_and_rotate_d2_54( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)3U, + .snd = (size_t)3U}))[0U], + t[3U])); + libcrux_sha3_generic_keccak_KeccakState_17 *uu____18 = self; + libcrux_sha3_generic_keccak_set_80_04( + uu____18, (size_t)4U, (size_t)3U, + libcrux_sha3_simd_portable_xor_and_rotate_d2_4c( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)4U, + .snd = (size_t)3U}))[0U], + t[3U])); + libcrux_sha3_generic_keccak_KeccakState_17 *uu____19 = self; + libcrux_sha3_generic_keccak_set_80_04( + uu____19, (size_t)0U, (size_t)4U, + libcrux_sha3_simd_portable_xor_and_rotate_d2_ce( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)0U, + .snd = (size_t)4U}))[0U], + t[4U])); + libcrux_sha3_generic_keccak_KeccakState_17 *uu____20 = self; + libcrux_sha3_generic_keccak_set_80_04( + uu____20, (size_t)1U, (size_t)4U, + libcrux_sha3_simd_portable_xor_and_rotate_d2_77( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)1U, + .snd = (size_t)4U}))[0U], + t[4U])); + libcrux_sha3_generic_keccak_KeccakState_17 *uu____21 = self; + libcrux_sha3_generic_keccak_set_80_04( + uu____21, (size_t)2U, (size_t)4U, + libcrux_sha3_simd_portable_xor_and_rotate_d2_25( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)2U, + .snd = (size_t)4U}))[0U], + t[4U])); + libcrux_sha3_generic_keccak_KeccakState_17 *uu____22 = self; + libcrux_sha3_generic_keccak_set_80_04( + uu____22, (size_t)3U, (size_t)4U, + libcrux_sha3_simd_portable_xor_and_rotate_d2_af( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)3U, + .snd = (size_t)4U}))[0U], + t[4U])); + libcrux_sha3_generic_keccak_KeccakState_17 *uu____23 = self; + libcrux_sha3_generic_keccak_set_80_04( + uu____23, (size_t)4U, (size_t)4U, + libcrux_sha3_simd_portable_xor_and_rotate_d2_fd( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)4U, + .snd = (size_t)4U}))[0U], + t[4U])); +} + +/** +This function found in impl {libcrux_sha3::generic_keccak::KeccakState[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.pi_80 with types uint64_t with const generics - N= 1 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_pi_1d( - libcrux_sha3_generic_keccak_KeccakState_48 *s) { - uint64_t old[5U][5U]; - memcpy(old, s->st, (size_t)5U * sizeof(uint64_t[5U])); - s->st[0U][1U] = old[1U][1U]; - s->st[0U][2U] = old[2U][2U]; - s->st[0U][3U] = old[3U][3U]; - s->st[0U][4U] = old[4U][4U]; - s->st[1U][0U] = old[0U][3U]; - s->st[1U][1U] = old[1U][4U]; - s->st[1U][2U] = old[2U][0U]; - s->st[1U][3U] = old[3U][1U]; - s->st[1U][4U] = old[4U][2U]; - s->st[2U][0U] = old[0U][1U]; - s->st[2U][1U] = old[1U][2U]; - s->st[2U][2U] = old[2U][3U]; - s->st[2U][3U] = old[3U][4U]; - s->st[2U][4U] = old[4U][0U]; - s->st[3U][0U] = old[0U][4U]; - s->st[3U][1U] = old[1U][0U]; - s->st[3U][2U] = old[2U][1U]; - s->st[3U][3U] = old[3U][2U]; - s->st[3U][4U] = old[4U][3U]; - s->st[4U][0U] = old[0U][2U]; - s->st[4U][1U] = old[1U][3U]; - s->st[4U][2U] = old[2U][4U]; - s->st[4U][3U] = old[3U][0U]; - s->st[4U][4U] = old[4U][1U]; -} - -/** -A monomorphic instance of libcrux_sha3.generic_keccak.chi +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_pi_80_04( + libcrux_sha3_generic_keccak_KeccakState_17 *self) { + libcrux_sha3_generic_keccak_KeccakState_17 old = self[0U]; + libcrux_sha3_generic_keccak_set_80_04( + self, (size_t)1U, (size_t)0U, + libcrux_sha3_generic_keccak_index_c2_04( + &old, (KRML_CLITERAL(size_t_x2){.fst = (size_t)0U, + .snd = (size_t)3U}))[0U]); + libcrux_sha3_generic_keccak_set_80_04( + self, (size_t)2U, (size_t)0U, + libcrux_sha3_generic_keccak_index_c2_04( + &old, (KRML_CLITERAL(size_t_x2){.fst = (size_t)0U, + .snd = (size_t)1U}))[0U]); + libcrux_sha3_generic_keccak_set_80_04( + self, (size_t)3U, (size_t)0U, + libcrux_sha3_generic_keccak_index_c2_04( + &old, (KRML_CLITERAL(size_t_x2){.fst = (size_t)0U, + .snd = (size_t)4U}))[0U]); + libcrux_sha3_generic_keccak_set_80_04( + self, (size_t)4U, (size_t)0U, + libcrux_sha3_generic_keccak_index_c2_04( + &old, (KRML_CLITERAL(size_t_x2){.fst = (size_t)0U, + .snd = (size_t)2U}))[0U]); + libcrux_sha3_generic_keccak_set_80_04( + self, (size_t)0U, (size_t)1U, + libcrux_sha3_generic_keccak_index_c2_04( + &old, (KRML_CLITERAL(size_t_x2){.fst = (size_t)1U, + .snd = (size_t)1U}))[0U]); + libcrux_sha3_generic_keccak_set_80_04( + self, (size_t)1U, (size_t)1U, + libcrux_sha3_generic_keccak_index_c2_04( + &old, (KRML_CLITERAL(size_t_x2){.fst = (size_t)1U, + .snd = (size_t)4U}))[0U]); + libcrux_sha3_generic_keccak_set_80_04( + self, (size_t)2U, (size_t)1U, + libcrux_sha3_generic_keccak_index_c2_04( + &old, (KRML_CLITERAL(size_t_x2){.fst = (size_t)1U, + .snd = (size_t)2U}))[0U]); + libcrux_sha3_generic_keccak_set_80_04( + self, (size_t)3U, (size_t)1U, + libcrux_sha3_generic_keccak_index_c2_04( + &old, (KRML_CLITERAL(size_t_x2){.fst = (size_t)1U, + .snd = (size_t)0U}))[0U]); + libcrux_sha3_generic_keccak_set_80_04( + self, (size_t)4U, (size_t)1U, + libcrux_sha3_generic_keccak_index_c2_04( + &old, (KRML_CLITERAL(size_t_x2){.fst = (size_t)1U, + .snd = (size_t)3U}))[0U]); + libcrux_sha3_generic_keccak_set_80_04( + self, (size_t)0U, (size_t)2U, + libcrux_sha3_generic_keccak_index_c2_04( + &old, (KRML_CLITERAL(size_t_x2){.fst = (size_t)2U, + .snd = (size_t)2U}))[0U]); + libcrux_sha3_generic_keccak_set_80_04( + self, (size_t)1U, (size_t)2U, + libcrux_sha3_generic_keccak_index_c2_04( + &old, (KRML_CLITERAL(size_t_x2){.fst = (size_t)2U, + .snd = (size_t)0U}))[0U]); + libcrux_sha3_generic_keccak_set_80_04( + self, (size_t)2U, (size_t)2U, + libcrux_sha3_generic_keccak_index_c2_04( + &old, (KRML_CLITERAL(size_t_x2){.fst = (size_t)2U, + .snd = (size_t)3U}))[0U]); + libcrux_sha3_generic_keccak_set_80_04( + self, (size_t)3U, (size_t)2U, + libcrux_sha3_generic_keccak_index_c2_04( + &old, (KRML_CLITERAL(size_t_x2){.fst = (size_t)2U, + .snd = (size_t)1U}))[0U]); + libcrux_sha3_generic_keccak_set_80_04( + self, (size_t)4U, (size_t)2U, + libcrux_sha3_generic_keccak_index_c2_04( + &old, (KRML_CLITERAL(size_t_x2){.fst = (size_t)2U, + .snd = (size_t)4U}))[0U]); + libcrux_sha3_generic_keccak_set_80_04( + self, (size_t)0U, (size_t)3U, + libcrux_sha3_generic_keccak_index_c2_04( + &old, (KRML_CLITERAL(size_t_x2){.fst = (size_t)3U, + .snd = (size_t)3U}))[0U]); + libcrux_sha3_generic_keccak_set_80_04( + self, (size_t)1U, (size_t)3U, + libcrux_sha3_generic_keccak_index_c2_04( + &old, (KRML_CLITERAL(size_t_x2){.fst = (size_t)3U, + .snd = (size_t)1U}))[0U]); + libcrux_sha3_generic_keccak_set_80_04( + self, (size_t)2U, (size_t)3U, + libcrux_sha3_generic_keccak_index_c2_04( + &old, (KRML_CLITERAL(size_t_x2){.fst = (size_t)3U, + .snd = (size_t)4U}))[0U]); + libcrux_sha3_generic_keccak_set_80_04( + self, (size_t)3U, (size_t)3U, + libcrux_sha3_generic_keccak_index_c2_04( + &old, (KRML_CLITERAL(size_t_x2){.fst = (size_t)3U, + .snd = (size_t)2U}))[0U]); + libcrux_sha3_generic_keccak_set_80_04( + self, (size_t)4U, (size_t)3U, + libcrux_sha3_generic_keccak_index_c2_04( + &old, (KRML_CLITERAL(size_t_x2){.fst = (size_t)3U, + .snd = (size_t)0U}))[0U]); + libcrux_sha3_generic_keccak_set_80_04( + self, (size_t)0U, (size_t)4U, + libcrux_sha3_generic_keccak_index_c2_04( + &old, (KRML_CLITERAL(size_t_x2){.fst = (size_t)4U, + .snd = (size_t)4U}))[0U]); + libcrux_sha3_generic_keccak_set_80_04( + self, (size_t)1U, (size_t)4U, + libcrux_sha3_generic_keccak_index_c2_04( + &old, (KRML_CLITERAL(size_t_x2){.fst = (size_t)4U, + .snd = (size_t)2U}))[0U]); + libcrux_sha3_generic_keccak_set_80_04( + self, (size_t)2U, (size_t)4U, + libcrux_sha3_generic_keccak_index_c2_04( + &old, (KRML_CLITERAL(size_t_x2){.fst = (size_t)4U, + .snd = (size_t)0U}))[0U]); + libcrux_sha3_generic_keccak_set_80_04( + self, (size_t)3U, (size_t)4U, + libcrux_sha3_generic_keccak_index_c2_04( + &old, (KRML_CLITERAL(size_t_x2){.fst = (size_t)4U, + .snd = (size_t)3U}))[0U]); + libcrux_sha3_generic_keccak_set_80_04( + self, (size_t)4U, (size_t)4U, + libcrux_sha3_generic_keccak_index_c2_04( + &old, (KRML_CLITERAL(size_t_x2){.fst = (size_t)4U, + .snd = (size_t)1U}))[0U]); +} + +/** +This function found in impl {libcrux_sha3::generic_keccak::KeccakState[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.chi_80 with types uint64_t with const generics - N= 1 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_chi_12( - libcrux_sha3_generic_keccak_KeccakState_48 *s) { - uint64_t old[5U][5U]; - memcpy(old, s->st, (size_t)5U * sizeof(uint64_t[5U])); +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_chi_80_04( + libcrux_sha3_generic_keccak_KeccakState_17 *self) { + libcrux_sha3_generic_keccak_KeccakState_17 old = self[0U]; for (size_t i0 = (size_t)0U; i0 < (size_t)5U; i0++) { size_t i1 = i0; for (size_t i = (size_t)0U; i < (size_t)5U; i++) { size_t j = i; - s->st[i1][j] = libcrux_sha3_portable_keccak_and_not_xor_5a( - s->st[i1][j], old[i1][(j + (size_t)2U) % (size_t)5U], - old[i1][(j + (size_t)1U) % (size_t)5U]); + libcrux_sha3_generic_keccak_set_80_04( + self, i1, j, + libcrux_sha3_simd_portable_and_not_xor_d2( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = i1, .snd = j}))[0U], + libcrux_sha3_generic_keccak_index_c2_04( + &old, + (KRML_CLITERAL(size_t_x2){ + .fst = i1, .snd = (j + (size_t)2U) % (size_t)5U}))[0U], + libcrux_sha3_generic_keccak_index_c2_04( + &old, + (KRML_CLITERAL(size_t_x2){ + .fst = i1, .snd = (j + (size_t)1U) % (size_t)5U}))[0U])); } } } /** -A monomorphic instance of libcrux_sha3.generic_keccak.iota +This function found in impl {libcrux_sha3::generic_keccak::KeccakState[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.iota_80 with types uint64_t with const generics - N= 1 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_iota_62( - libcrux_sha3_generic_keccak_KeccakState_48 *s, size_t i) { - s->st[0U][0U] = libcrux_sha3_portable_keccak_xor_constant_5a( - s->st[0U][0U], libcrux_sha3_generic_keccak_ROUNDCONSTANTS[i]); +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_iota_80_04( + libcrux_sha3_generic_keccak_KeccakState_17 *self, size_t i) { + libcrux_sha3_generic_keccak_set_80_04( + self, (size_t)0U, (size_t)0U, + libcrux_sha3_simd_portable_xor_constant_d2( + libcrux_sha3_generic_keccak_index_c2_04( + self, (KRML_CLITERAL(size_t_x2){.fst = (size_t)0U, + .snd = (size_t)0U}))[0U], + libcrux_sha3_generic_keccak_constants_ROUNDCONSTANTS[i])); } /** -A monomorphic instance of libcrux_sha3.generic_keccak.keccakf1600 +This function found in impl {libcrux_sha3::generic_keccak::KeccakState[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.keccakf1600_80 with types uint64_t with const generics - N= 1 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_keccakf1600_21( - libcrux_sha3_generic_keccak_KeccakState_48 *s) { +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_keccakf1600_80_04( + libcrux_sha3_generic_keccak_KeccakState_17 *self) { for (size_t i = (size_t)0U; i < (size_t)24U; i++) { size_t i0 = i; - libcrux_sha3_generic_keccak_theta_rho_16(s); - libcrux_sha3_generic_keccak_pi_1d(s); - libcrux_sha3_generic_keccak_chi_12(s); - libcrux_sha3_generic_keccak_iota_62(s, i0); + uint64_t t[5U]; + libcrux_sha3_generic_keccak_theta_80_04(self, t); + libcrux_sha3_generic_keccak_KeccakState_17 *uu____0 = self; + uint64_t uu____1[5U]; + memcpy(uu____1, t, (size_t)5U * sizeof(uint64_t)); + libcrux_sha3_generic_keccak_rho_80_04(uu____0, uu____1); + libcrux_sha3_generic_keccak_pi_80_04(self); + libcrux_sha3_generic_keccak_chi_80_04(self); + libcrux_sha3_generic_keccak_iota_80_04(self, i0); } } /** -A monomorphic instance of libcrux_sha3.generic_keccak.absorb_block +This function found in impl {libcrux_sha3::generic_keccak::KeccakState[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_block_80 with types uint64_t with const generics - N= 1 - RATE= 72 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_block_df( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice blocks[1U]) { - uint64_t(*uu____0)[5U] = s->st; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak_load_block_5a_b8(uu____0, uu____1); - libcrux_sha3_generic_keccak_keccakf1600_21(s); +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_block_80_c6( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice *blocks, + size_t start) { + libcrux_sha3_simd_portable_load_block_a1_f8(self, blocks, start); + libcrux_sha3_generic_keccak_keccakf1600_80_04(self); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full +A monomorphic instance of libcrux_sha3.simd.portable.load_last with const generics - RATE= 72 +- DELIMITER= 6 */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_df( - uint64_t (*s)[5U], uint8_t blocks[1U][200U]) { - Eurydice_slice buf[1U] = { - Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t)}; - libcrux_sha3_portable_keccak_load_block_2c(s, buf); +static KRML_MUSTINLINE void libcrux_sha3_simd_portable_load_last_96( + uint64_t *state, Eurydice_slice blocks, size_t start, size_t len) { + uint8_t buffer[72U] = {0U}; + Eurydice_slice_copy( + Eurydice_array_to_subslice3(buffer, (size_t)0U, len, uint8_t *), + Eurydice_slice_subslice3(blocks, start, start + len, uint8_t *), uint8_t); + buffer[len] = 6U; + size_t uu____0 = (size_t)72U - (size_t)1U; + buffer[uu____0] = (uint32_t)buffer[uu____0] | 128U; + libcrux_sha3_simd_portable_load_block_f8( + state, Eurydice_array_to_slice((size_t)72U, buffer, uint8_t), (size_t)0U); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::Absorb<1usize> for +libcrux_sha3::generic_keccak::KeccakState[core::marker::Sized, +libcrux_sha3::simd::portable::{libcrux_sha3::traits::KeccakItem<1usize> for +u64}]} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full_5a +A monomorphic instance of libcrux_sha3.simd.portable.load_last_a1 with const generics - RATE= 72 +- DELIMITER= 6 */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_5a_d2( - uint64_t (*a)[5U], uint8_t b[1U][200U]) { - uint64_t(*uu____0)[5U] = a; - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_b[1U][200U]; - memcpy(copy_of_b, b, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak_load_block_full_df(uu____0, copy_of_b); +static inline void libcrux_sha3_simd_portable_load_last_a1_96( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice *input, + size_t start, size_t len) { + libcrux_sha3_simd_portable_load_last_96(self->st, input[0U], start, len); } /** -A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final +This function found in impl {libcrux_sha3::generic_keccak::KeccakState[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final_80 with types uint64_t with const generics - N= 1 - RATE= 72 - DELIM= 6 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_c7( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice last[1U]) { - size_t last_len = Eurydice_slice_len(last[0U], uint8_t); - uint8_t blocks[1U][200U] = {{0U}}; - for (size_t i = (size_t)0U; i < (size_t)1U; i++) { - size_t i0 = i; - if (last_len > (size_t)0U) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice2( - blocks[i0], (size_t)0U, last_len, uint8_t); - Eurydice_slice_copy(uu____0, last[i0], uint8_t); - } - blocks[i0][last_len] = 6U; - size_t uu____1 = i0; - size_t uu____2 = (size_t)72U - (size_t)1U; - blocks[uu____1][uu____2] = (uint32_t)blocks[uu____1][uu____2] | 128U; - } - uint64_t(*uu____3)[5U] = s->st; - uint8_t uu____4[1U][200U]; - memcpy(uu____4, blocks, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak_load_block_full_5a_d2(uu____3, uu____4); - libcrux_sha3_generic_keccak_keccakf1600_21(s); +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_80_9e( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice *last, + size_t start, size_t len) { + libcrux_sha3_simd_portable_load_last_a1_96(self, last, start, len); + libcrux_sha3_generic_keccak_keccakf1600_80_04(self); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.store_block +A monomorphic instance of libcrux_sha3.simd.portable.store_block with const generics - RATE= 72 */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_58( - uint64_t (*s)[5U], Eurydice_slice out[1U]) { - for (size_t i = (size_t)0U; i < (size_t)72U / (size_t)8U; i++) { +static KRML_MUSTINLINE void libcrux_sha3_simd_portable_store_block_f8( + uint64_t *s, Eurydice_slice out, size_t start, size_t len) { + size_t octets = len / (size_t)8U; + for (size_t i = (size_t)0U; i < octets; i++) { size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_slice_subslice2( - out[0U], (size_t)8U * i0, (size_t)8U * i0 + (size_t)8U, uint8_t); + Eurydice_slice uu____0 = Eurydice_slice_subslice3( + out, start + (size_t)8U * i0, start + (size_t)8U * i0 + (size_t)8U, + uint8_t *); uint8_t ret[8U]; - core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); + core_num__u64__to_le_bytes( + libcrux_sha3_traits_get_ij_04(s, i0 / (size_t)5U, i0 % (size_t)5U)[0U], + ret); Eurydice_slice_copy( uu____0, Eurydice_array_to_slice((size_t)8U, ret, uint8_t), uint8_t); } + size_t remaining = len % (size_t)8U; + if (remaining > (size_t)0U) { + Eurydice_slice uu____1 = Eurydice_slice_subslice3( + out, start + len - remaining, start + len, uint8_t *); + uint8_t ret[8U]; + core_num__u64__to_le_bytes( + libcrux_sha3_traits_get_ij_04(s, octets / (size_t)5U, + octets % (size_t)5U)[0U], + ret); + Eurydice_slice_copy( + uu____1, + Eurydice_array_to_subslice3(ret, (size_t)0U, remaining, uint8_t *), + uint8_t); + } } /** -A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full -with const generics -- RATE= 72 -*/ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_full_2d( - uint64_t (*s)[5U], uint8_t ret[1U][200U]) { - uint8_t out[200U] = {0U}; - Eurydice_slice buf[1U] = { - Eurydice_array_to_slice((size_t)200U, out, uint8_t)}; - libcrux_sha3_portable_keccak_store_block_58(s, buf); - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_out[200U]; - memcpy(copy_of_out, out, (size_t)200U * sizeof(uint8_t)); - memcpy(ret[0U], copy_of_out, (size_t)200U * sizeof(uint8_t)); -} - -/** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::Squeeze1 for +libcrux_sha3::generic_keccak::KeccakState[core::marker::Sized, +libcrux_sha3::simd::portable::{libcrux_sha3::traits::KeccakItem<1usize> for +u64}]} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full_5a +A monomorphic instance of libcrux_sha3.simd.portable.squeeze_13 with const generics - RATE= 72 */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_full_5a_29( - uint64_t (*a)[5U], uint8_t ret[1U][200U]) { - libcrux_sha3_portable_keccak_store_block_full_2d(a, ret); +static inline void libcrux_sha3_simd_portable_squeeze_13_f8( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice out, + size_t start, size_t len) { + libcrux_sha3_simd_portable_store_block_f8(self->st, out, start, len); } /** -A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_and_last -with types uint64_t +A monomorphic instance of libcrux_sha3.generic_keccak.portable.keccak1 with const generics -- N= 1 - RATE= 72 +- DELIM= 6 */ -static KRML_MUSTINLINE void -libcrux_sha3_generic_keccak_squeeze_first_and_last_c5( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak_store_block_full_5a_29(s->st, b); - for (size_t i = (size_t)0U; i < (size_t)1U; i++) { +static inline void libcrux_sha3_generic_keccak_portable_keccak1_96( + Eurydice_slice data, Eurydice_slice out) { + libcrux_sha3_generic_keccak_KeccakState_17 s = + libcrux_sha3_generic_keccak_new_80_04(); + size_t data_len = Eurydice_slice_len(data, uint8_t); + for (size_t i = (size_t)0U; i < data_len / (size_t)72U; i++) { size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range_b3 lit; - lit.start = (size_t)0U; - lit.end = Eurydice_slice_len(out[i0], uint8_t); - Eurydice_slice_copy( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range_b3), - uint8_t); + Eurydice_slice buf[1U] = {data}; + libcrux_sha3_generic_keccak_absorb_block_80_c6(&s, buf, i0 * (size_t)72U); + } + size_t rem = data_len % (size_t)72U; + Eurydice_slice buf[1U] = {data}; + libcrux_sha3_generic_keccak_absorb_final_80_9e(&s, buf, data_len - rem, rem); + size_t outlen = Eurydice_slice_len(out, uint8_t); + size_t blocks = outlen / (size_t)72U; + size_t last = outlen - outlen % (size_t)72U; + if (blocks == (size_t)0U) { + libcrux_sha3_simd_portable_squeeze_13_f8(&s, out, (size_t)0U, outlen); + } else { + libcrux_sha3_simd_portable_squeeze_13_f8(&s, out, (size_t)0U, (size_t)72U); + for (size_t i = (size_t)1U; i < blocks; i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_keccakf1600_80_04(&s); + libcrux_sha3_simd_portable_squeeze_13_f8(&s, out, i0 * (size_t)72U, + (size_t)72U); + } + if (last < outlen) { + libcrux_sha3_generic_keccak_keccakf1600_80_04(&s); + libcrux_sha3_simd_portable_squeeze_13_f8(&s, out, last, outlen - last); + } } } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} -*/ -/** -A monomorphic instance of libcrux_sha3.portable_keccak.store_block_5a -with const generics -- RATE= 72 + A portable SHA3 512 implementation. */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_5a_59( - uint64_t (*a)[5U], Eurydice_slice b[1U]) { - libcrux_sha3_portable_keccak_store_block_58(a, b); +static KRML_MUSTINLINE void libcrux_sha3_portable_sha512(Eurydice_slice digest, + Eurydice_slice data) { + libcrux_sha3_generic_keccak_portable_keccak1_96(data, digest); } /** -A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_block -with types uint64_t -with const generics -- N= 1 -- RATE= 72 -*/ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_first_block_84( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { - libcrux_sha3_portable_keccak_store_block_5a_59(s->st, out); -} - -/** -A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_next_block -with types uint64_t -with const generics -- N= 1 -- RATE= 72 -*/ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_next_block_fc( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_keccakf1600_21(s); - libcrux_sha3_portable_keccak_store_block_5a_59(s->st, out); -} - -/** -A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_last -with types uint64_t -with const generics -- N= 1 -- RATE= 72 -*/ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_last_cf( - libcrux_sha3_generic_keccak_KeccakState_48 s, Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_keccakf1600_21(&s); - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak_store_block_full_5a_29(s.st, b); - for (size_t i = (size_t)0U; i < (size_t)1U; i++) { - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range_b3 lit; - lit.start = (size_t)0U; - lit.end = Eurydice_slice_len(out[i0], uint8_t); - Eurydice_slice_copy( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range_b3), - uint8_t); - } -} - -/** -A monomorphic instance of libcrux_sha3.generic_keccak.keccak -with types uint64_t -with const generics -- N= 1 -- RATE= 72 -- DELIM= 6 -*/ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_keccak_e9( - Eurydice_slice data[1U], Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_KeccakState_48 s = - libcrux_sha3_generic_keccak_new_1e_f4(); - for (size_t i = (size_t)0U; - i < Eurydice_slice_len(data[0U], uint8_t) / (size_t)72U; i++) { - size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState_48 *uu____0 = &s; - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_data[1U]; - memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak_slice_n_5a(copy_of_data, i0 * (size_t)72U, - (size_t)72U, ret); - libcrux_sha3_generic_keccak_absorb_block_df(uu____0, ret); - } - size_t rem = Eurydice_slice_len(data[0U], uint8_t) % (size_t)72U; - libcrux_sha3_generic_keccak_KeccakState_48 *uu____2 = &s; - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_data[1U]; - memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak_slice_n_5a( - copy_of_data, Eurydice_slice_len(data[0U], uint8_t) - rem, rem, ret); - libcrux_sha3_generic_keccak_absorb_final_c7(uu____2, ret); - size_t outlen = Eurydice_slice_len(out[0U], uint8_t); - size_t blocks = outlen / (size_t)72U; - size_t last = outlen - outlen % (size_t)72U; - if (blocks == (size_t)0U) { - libcrux_sha3_generic_keccak_squeeze_first_and_last_c5(&s, out); - } else { - Eurydice_slice_uint8_t_1size_t__x2 uu____4 = - libcrux_sha3_portable_keccak_split_at_mut_n_5a(out, (size_t)72U); - Eurydice_slice o0[1U]; - memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice o1[1U]; - memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block_84(&s, o0); - core_ops_range_Range_b3 iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter( - (CLITERAL(core_ops_range_Range_b3){.start = (size_t)1U, - .end = blocks}), - core_ops_range_Range_b3, core_ops_range_Range_b3); - while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( - &iter, size_t, Option_b3) - .tag == None) { - break; - } else { - Eurydice_slice_uint8_t_1size_t__x2 uu____5 = - libcrux_sha3_portable_keccak_split_at_mut_n_5a(o1, (size_t)72U); - Eurydice_slice o[1U]; - memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice orest[1U]; - memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block_fc(&s, o); - memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); - } - } - if (last < outlen) { - libcrux_sha3_generic_keccak_squeeze_last_cf(s, o1); - } - } -} - -/** -A monomorphic instance of libcrux_sha3.portable.keccakx1 -with const generics -- RATE= 72 -- DELIM= 6 -*/ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccakx1_ce( - Eurydice_slice data[1U], Eurydice_slice out[1U]) { - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_data[1U]; - memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_keccak_e9(copy_of_data, out); -} - -/** - A portable SHA3 512 implementation. -*/ -static KRML_MUSTINLINE void libcrux_sha3_portable_sha512(Eurydice_slice digest, - Eurydice_slice data) { - Eurydice_slice buf0[1U] = {data}; - Eurydice_slice buf[1U] = {digest}; - libcrux_sha3_portable_keccakx1_ce(buf0, buf); -} - -/** -A monomorphic instance of libcrux_sha3.portable_keccak.load_block +A monomorphic instance of libcrux_sha3.simd.portable.load_block with const generics - RATE= 136 */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_2c0( - uint64_t (*s)[5U], Eurydice_slice blocks[1U]) { +static KRML_MUSTINLINE void libcrux_sha3_simd_portable_load_block_5b( + uint64_t *state, Eurydice_slice blocks, size_t start) { + uint64_t state_flat[25U] = {0U}; for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)8U; i++) { size_t i0 = i; + size_t offset = start + (size_t)8U * i0; uint8_t uu____0[8U]; - Result_56 dst; + Result_15 dst; Eurydice_slice_to_array2( &dst, - Eurydice_slice_subslice2(blocks[0U], (size_t)8U * i0, - (size_t)8U * i0 + (size_t)8U, uint8_t), - Eurydice_slice, uint8_t[8U]); - unwrap_41_ac(dst, uu____0); - size_t uu____1 = i0 / (size_t)5U; - size_t uu____2 = i0 % (size_t)5U; - s[uu____1][uu____2] = - s[uu____1][uu____2] ^ core_num__u64_9__from_le_bytes(uu____0); + Eurydice_slice_subslice3(blocks, offset, offset + (size_t)8U, + uint8_t *), + Eurydice_slice, uint8_t[8U], TryFromSliceError); + unwrap_26_68(dst, uu____0); + state_flat[i0] = core_num__u64__from_le_bytes(uu____0); + } + for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)8U; i++) { + size_t i0 = i; + libcrux_sha3_traits_set_ij_04( + state, i0 / (size_t)5U, i0 % (size_t)5U, + libcrux_sha3_traits_get_ij_04(state, i0 / (size_t)5U, + i0 % (size_t)5U)[0U] ^ + state_flat[i0]); } } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::Absorb<1usize> for +libcrux_sha3::generic_keccak::KeccakState[core::marker::Sized, +libcrux_sha3::simd::portable::{libcrux_sha3::traits::KeccakItem<1usize> for +u64}]} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.load_block_5a +A monomorphic instance of libcrux_sha3.simd.portable.load_block_a1 with const generics - RATE= 136 */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_5a_b80( - uint64_t (*a)[5U], Eurydice_slice b[1U]) { - uint64_t(*uu____0)[5U] = a; - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_b[1U]; - memcpy(copy_of_b, b, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak_load_block_2c0(uu____0, copy_of_b); +static inline void libcrux_sha3_simd_portable_load_block_a1_5b( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice *input, + size_t start) { + libcrux_sha3_simd_portable_load_block_5b(self->st, input[0U], start); } /** -A monomorphic instance of libcrux_sha3.generic_keccak.absorb_block +This function found in impl {libcrux_sha3::generic_keccak::KeccakState[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_block_80 with types uint64_t with const generics - N= 1 - RATE= 136 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_block_df0( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice blocks[1U]) { - uint64_t(*uu____0)[5U] = s->st; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak_load_block_5a_b80(uu____0, uu____1); - libcrux_sha3_generic_keccak_keccakf1600_21(s); +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_block_80_c60( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice *blocks, + size_t start) { + libcrux_sha3_simd_portable_load_block_a1_5b(self, blocks, start); + libcrux_sha3_generic_keccak_keccakf1600_80_04(self); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full +A monomorphic instance of libcrux_sha3.simd.portable.load_last with const generics - RATE= 136 +- DELIMITER= 6 */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_df0( - uint64_t (*s)[5U], uint8_t blocks[1U][200U]) { - Eurydice_slice buf[1U] = { - Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t)}; - libcrux_sha3_portable_keccak_load_block_2c0(s, buf); +static KRML_MUSTINLINE void libcrux_sha3_simd_portable_load_last_ad( + uint64_t *state, Eurydice_slice blocks, size_t start, size_t len) { + uint8_t buffer[136U] = {0U}; + Eurydice_slice_copy( + Eurydice_array_to_subslice3(buffer, (size_t)0U, len, uint8_t *), + Eurydice_slice_subslice3(blocks, start, start + len, uint8_t *), uint8_t); + buffer[len] = 6U; + size_t uu____0 = (size_t)136U - (size_t)1U; + buffer[uu____0] = (uint32_t)buffer[uu____0] | 128U; + libcrux_sha3_simd_portable_load_block_5b( + state, Eurydice_array_to_slice((size_t)136U, buffer, uint8_t), + (size_t)0U); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::Absorb<1usize> for +libcrux_sha3::generic_keccak::KeccakState[core::marker::Sized, +libcrux_sha3::simd::portable::{libcrux_sha3::traits::KeccakItem<1usize> for +u64}]} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full_5a +A monomorphic instance of libcrux_sha3.simd.portable.load_last_a1 with const generics - RATE= 136 +- DELIMITER= 6 */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_5a_d20( - uint64_t (*a)[5U], uint8_t b[1U][200U]) { - uint64_t(*uu____0)[5U] = a; - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_b[1U][200U]; - memcpy(copy_of_b, b, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak_load_block_full_df0(uu____0, copy_of_b); +static inline void libcrux_sha3_simd_portable_load_last_a1_ad( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice *input, + size_t start, size_t len) { + libcrux_sha3_simd_portable_load_last_ad(self->st, input[0U], start, len); } /** -A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final +This function found in impl {libcrux_sha3::generic_keccak::KeccakState[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final_80 with types uint64_t with const generics - N= 1 - RATE= 136 - DELIM= 6 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_c70( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice last[1U]) { - size_t last_len = Eurydice_slice_len(last[0U], uint8_t); - uint8_t blocks[1U][200U] = {{0U}}; - for (size_t i = (size_t)0U; i < (size_t)1U; i++) { - size_t i0 = i; - if (last_len > (size_t)0U) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice2( - blocks[i0], (size_t)0U, last_len, uint8_t); - Eurydice_slice_copy(uu____0, last[i0], uint8_t); - } - blocks[i0][last_len] = 6U; - size_t uu____1 = i0; - size_t uu____2 = (size_t)136U - (size_t)1U; - blocks[uu____1][uu____2] = (uint32_t)blocks[uu____1][uu____2] | 128U; - } - uint64_t(*uu____3)[5U] = s->st; - uint8_t uu____4[1U][200U]; - memcpy(uu____4, blocks, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak_load_block_full_5a_d20(uu____3, uu____4); - libcrux_sha3_generic_keccak_keccakf1600_21(s); +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_80_9e0( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice *last, + size_t start, size_t len) { + libcrux_sha3_simd_portable_load_last_a1_ad(self, last, start, len); + libcrux_sha3_generic_keccak_keccakf1600_80_04(self); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.store_block +A monomorphic instance of libcrux_sha3.simd.portable.store_block with const generics - RATE= 136 */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_580( - uint64_t (*s)[5U], Eurydice_slice out[1U]) { - for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)8U; i++) { +static KRML_MUSTINLINE void libcrux_sha3_simd_portable_store_block_5b( + uint64_t *s, Eurydice_slice out, size_t start, size_t len) { + size_t octets = len / (size_t)8U; + for (size_t i = (size_t)0U; i < octets; i++) { size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_slice_subslice2( - out[0U], (size_t)8U * i0, (size_t)8U * i0 + (size_t)8U, uint8_t); + Eurydice_slice uu____0 = Eurydice_slice_subslice3( + out, start + (size_t)8U * i0, start + (size_t)8U * i0 + (size_t)8U, + uint8_t *); uint8_t ret[8U]; - core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); + core_num__u64__to_le_bytes( + libcrux_sha3_traits_get_ij_04(s, i0 / (size_t)5U, i0 % (size_t)5U)[0U], + ret); Eurydice_slice_copy( uu____0, Eurydice_array_to_slice((size_t)8U, ret, uint8_t), uint8_t); } -} - -/** -A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full -with const generics -- RATE= 136 -*/ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_full_2d0( - uint64_t (*s)[5U], uint8_t ret[1U][200U]) { - uint8_t out[200U] = {0U}; - Eurydice_slice buf[1U] = { - Eurydice_array_to_slice((size_t)200U, out, uint8_t)}; - libcrux_sha3_portable_keccak_store_block_580(s, buf); - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_out[200U]; - memcpy(copy_of_out, out, (size_t)200U * sizeof(uint8_t)); - memcpy(ret[0U], copy_of_out, (size_t)200U * sizeof(uint8_t)); -} - -/** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} -*/ -/** -A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full_5a -with const generics -- RATE= 136 -*/ -static KRML_MUSTINLINE void -libcrux_sha3_portable_keccak_store_block_full_5a_290(uint64_t (*a)[5U], - uint8_t ret[1U][200U]) { - libcrux_sha3_portable_keccak_store_block_full_2d0(a, ret); -} - -/** -A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_and_last -with types uint64_t -with const generics -- N= 1 -- RATE= 136 -*/ -static KRML_MUSTINLINE void -libcrux_sha3_generic_keccak_squeeze_first_and_last_c50( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak_store_block_full_5a_290(s->st, b); - for (size_t i = (size_t)0U; i < (size_t)1U; i++) { - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range_b3 lit; - lit.start = (size_t)0U; - lit.end = Eurydice_slice_len(out[i0], uint8_t); + size_t remaining = len % (size_t)8U; + if (remaining > (size_t)0U) { + Eurydice_slice uu____1 = Eurydice_slice_subslice3( + out, start + len - remaining, start + len, uint8_t *); + uint8_t ret[8U]; + core_num__u64__to_le_bytes( + libcrux_sha3_traits_get_ij_04(s, octets / (size_t)5U, + octets % (size_t)5U)[0U], + ret); Eurydice_slice_copy( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range_b3), + uu____1, + Eurydice_array_to_subslice3(ret, (size_t)0U, remaining, uint8_t *), uint8_t); } } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} -*/ -/** -A monomorphic instance of libcrux_sha3.portable_keccak.store_block_5a -with const generics -- RATE= 136 -*/ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_5a_590( - uint64_t (*a)[5U], Eurydice_slice b[1U]) { - libcrux_sha3_portable_keccak_store_block_580(a, b); -} - -/** -A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_block -with types uint64_t -with const generics -- N= 1 -- RATE= 136 -*/ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_first_block_840( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { - libcrux_sha3_portable_keccak_store_block_5a_590(s->st, out); -} - -/** -A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_next_block -with types uint64_t -with const generics -- N= 1 -- RATE= 136 +This function found in impl {libcrux_sha3::traits::Squeeze1 for +libcrux_sha3::generic_keccak::KeccakState[core::marker::Sized, +libcrux_sha3::simd::portable::{libcrux_sha3::traits::KeccakItem<1usize> for +u64}]} */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_next_block_fc0( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_keccakf1600_21(s); - libcrux_sha3_portable_keccak_store_block_5a_590(s->st, out); -} - /** -A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_last -with types uint64_t +A monomorphic instance of libcrux_sha3.simd.portable.squeeze_13 with const generics -- N= 1 - RATE= 136 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_last_cf0( - libcrux_sha3_generic_keccak_KeccakState_48 s, Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_keccakf1600_21(&s); - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak_store_block_full_5a_290(s.st, b); - for (size_t i = (size_t)0U; i < (size_t)1U; i++) { - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range_b3 lit; - lit.start = (size_t)0U; - lit.end = Eurydice_slice_len(out[i0], uint8_t); - Eurydice_slice_copy( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range_b3), - uint8_t); - } +static inline void libcrux_sha3_simd_portable_squeeze_13_5b( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice out, + size_t start, size_t len) { + libcrux_sha3_simd_portable_store_block_5b(self->st, out, start, len); } /** -A monomorphic instance of libcrux_sha3.generic_keccak.keccak -with types uint64_t +A monomorphic instance of libcrux_sha3.generic_keccak.portable.keccak1 with const generics -- N= 1 - RATE= 136 - DELIM= 6 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_keccak_e90( - Eurydice_slice data[1U], Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_KeccakState_48 s = - libcrux_sha3_generic_keccak_new_1e_f4(); - for (size_t i = (size_t)0U; - i < Eurydice_slice_len(data[0U], uint8_t) / (size_t)136U; i++) { +static inline void libcrux_sha3_generic_keccak_portable_keccak1_ad( + Eurydice_slice data, Eurydice_slice out) { + libcrux_sha3_generic_keccak_KeccakState_17 s = + libcrux_sha3_generic_keccak_new_80_04(); + size_t data_len = Eurydice_slice_len(data, uint8_t); + for (size_t i = (size_t)0U; i < data_len / (size_t)136U; i++) { size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState_48 *uu____0 = &s; - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_data[1U]; - memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak_slice_n_5a(copy_of_data, i0 * (size_t)136U, - (size_t)136U, ret); - libcrux_sha3_generic_keccak_absorb_block_df0(uu____0, ret); - } - size_t rem = Eurydice_slice_len(data[0U], uint8_t) % (size_t)136U; - libcrux_sha3_generic_keccak_KeccakState_48 *uu____2 = &s; - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_data[1U]; - memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak_slice_n_5a( - copy_of_data, Eurydice_slice_len(data[0U], uint8_t) - rem, rem, ret); - libcrux_sha3_generic_keccak_absorb_final_c70(uu____2, ret); - size_t outlen = Eurydice_slice_len(out[0U], uint8_t); + Eurydice_slice buf[1U] = {data}; + libcrux_sha3_generic_keccak_absorb_block_80_c60(&s, buf, i0 * (size_t)136U); + } + size_t rem = data_len % (size_t)136U; + Eurydice_slice buf[1U] = {data}; + libcrux_sha3_generic_keccak_absorb_final_80_9e0(&s, buf, data_len - rem, rem); + size_t outlen = Eurydice_slice_len(out, uint8_t); size_t blocks = outlen / (size_t)136U; size_t last = outlen - outlen % (size_t)136U; if (blocks == (size_t)0U) { - libcrux_sha3_generic_keccak_squeeze_first_and_last_c50(&s, out); + libcrux_sha3_simd_portable_squeeze_13_5b(&s, out, (size_t)0U, outlen); } else { - Eurydice_slice_uint8_t_1size_t__x2 uu____4 = - libcrux_sha3_portable_keccak_split_at_mut_n_5a(out, (size_t)136U); - Eurydice_slice o0[1U]; - memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice o1[1U]; - memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block_840(&s, o0); - core_ops_range_Range_b3 iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter( - (CLITERAL(core_ops_range_Range_b3){.start = (size_t)1U, - .end = blocks}), - core_ops_range_Range_b3, core_ops_range_Range_b3); - while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( - &iter, size_t, Option_b3) - .tag == None) { - break; - } else { - Eurydice_slice_uint8_t_1size_t__x2 uu____5 = - libcrux_sha3_portable_keccak_split_at_mut_n_5a(o1, (size_t)136U); - Eurydice_slice o[1U]; - memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice orest[1U]; - memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block_fc0(&s, o); - memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); - } + libcrux_sha3_simd_portable_squeeze_13_5b(&s, out, (size_t)0U, (size_t)136U); + for (size_t i = (size_t)1U; i < blocks; i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_keccakf1600_80_04(&s); + libcrux_sha3_simd_portable_squeeze_13_5b(&s, out, i0 * (size_t)136U, + (size_t)136U); } if (last < outlen) { - libcrux_sha3_generic_keccak_squeeze_last_cf0(s, o1); + libcrux_sha3_generic_keccak_keccakf1600_80_04(&s); + libcrux_sha3_simd_portable_squeeze_13_5b(&s, out, last, outlen - last); } } } /** -A monomorphic instance of libcrux_sha3.portable.keccakx1 + A portable SHA3 256 implementation. +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_sha256(Eurydice_slice digest, + Eurydice_slice data) { + libcrux_sha3_generic_keccak_portable_keccak1_ad(data, digest); +} + +/** +A monomorphic instance of libcrux_sha3.simd.portable.load_last with const generics - RATE= 136 -- DELIM= 6 +- DELIMITER= 31 */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccakx1_ce0( - Eurydice_slice data[1U], Eurydice_slice out[1U]) { - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_data[1U]; - memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_keccak_e90(copy_of_data, out); +static KRML_MUSTINLINE void libcrux_sha3_simd_portable_load_last_ad0( + uint64_t *state, Eurydice_slice blocks, size_t start, size_t len) { + uint8_t buffer[136U] = {0U}; + Eurydice_slice_copy( + Eurydice_array_to_subslice3(buffer, (size_t)0U, len, uint8_t *), + Eurydice_slice_subslice3(blocks, start, start + len, uint8_t *), uint8_t); + buffer[len] = 31U; + size_t uu____0 = (size_t)136U - (size_t)1U; + buffer[uu____0] = (uint32_t)buffer[uu____0] | 128U; + libcrux_sha3_simd_portable_load_block_5b( + state, Eurydice_array_to_slice((size_t)136U, buffer, uint8_t), + (size_t)0U); } /** - A portable SHA3 256 implementation. +This function found in impl {libcrux_sha3::traits::Absorb<1usize> for +libcrux_sha3::generic_keccak::KeccakState[core::marker::Sized, +libcrux_sha3::simd::portable::{libcrux_sha3::traits::KeccakItem<1usize> for +u64}]} */ -static KRML_MUSTINLINE void libcrux_sha3_portable_sha256(Eurydice_slice digest, - Eurydice_slice data) { - Eurydice_slice buf0[1U] = {data}; - Eurydice_slice buf[1U] = {digest}; - libcrux_sha3_portable_keccakx1_ce0(buf0, buf); +/** +A monomorphic instance of libcrux_sha3.simd.portable.load_last_a1 +with const generics +- RATE= 136 +- DELIMITER= 31 +*/ +static inline void libcrux_sha3_simd_portable_load_last_a1_ad0( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice *input, + size_t start, size_t len) { + libcrux_sha3_simd_portable_load_last_ad0(self->st, input[0U], start, len); } /** -A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final +This function found in impl {libcrux_sha3::generic_keccak::KeccakState[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final_80 with types uint64_t with const generics - N= 1 - RATE= 136 - DELIM= 31 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_c71( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice last[1U]) { - size_t last_len = Eurydice_slice_len(last[0U], uint8_t); - uint8_t blocks[1U][200U] = {{0U}}; - for (size_t i = (size_t)0U; i < (size_t)1U; i++) { - size_t i0 = i; - if (last_len > (size_t)0U) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice2( - blocks[i0], (size_t)0U, last_len, uint8_t); - Eurydice_slice_copy(uu____0, last[i0], uint8_t); - } - blocks[i0][last_len] = 31U; - size_t uu____1 = i0; - size_t uu____2 = (size_t)136U - (size_t)1U; - blocks[uu____1][uu____2] = (uint32_t)blocks[uu____1][uu____2] | 128U; - } - uint64_t(*uu____3)[5U] = s->st; - uint8_t uu____4[1U][200U]; - memcpy(uu____4, blocks, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak_load_block_full_5a_d20(uu____3, uu____4); - libcrux_sha3_generic_keccak_keccakf1600_21(s); +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_80_9e1( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice *last, + size_t start, size_t len) { + libcrux_sha3_simd_portable_load_last_a1_ad0(self, last, start, len); + libcrux_sha3_generic_keccak_keccakf1600_80_04(self); } /** -A monomorphic instance of libcrux_sha3.generic_keccak.keccak -with types uint64_t +A monomorphic instance of libcrux_sha3.generic_keccak.portable.keccak1 with const generics -- N= 1 - RATE= 136 - DELIM= 31 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_keccak_e91( - Eurydice_slice data[1U], Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_KeccakState_48 s = - libcrux_sha3_generic_keccak_new_1e_f4(); - for (size_t i = (size_t)0U; - i < Eurydice_slice_len(data[0U], uint8_t) / (size_t)136U; i++) { +static inline void libcrux_sha3_generic_keccak_portable_keccak1_ad0( + Eurydice_slice data, Eurydice_slice out) { + libcrux_sha3_generic_keccak_KeccakState_17 s = + libcrux_sha3_generic_keccak_new_80_04(); + size_t data_len = Eurydice_slice_len(data, uint8_t); + for (size_t i = (size_t)0U; i < data_len / (size_t)136U; i++) { size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState_48 *uu____0 = &s; - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_data[1U]; - memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak_slice_n_5a(copy_of_data, i0 * (size_t)136U, - (size_t)136U, ret); - libcrux_sha3_generic_keccak_absorb_block_df0(uu____0, ret); - } - size_t rem = Eurydice_slice_len(data[0U], uint8_t) % (size_t)136U; - libcrux_sha3_generic_keccak_KeccakState_48 *uu____2 = &s; - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_data[1U]; - memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak_slice_n_5a( - copy_of_data, Eurydice_slice_len(data[0U], uint8_t) - rem, rem, ret); - libcrux_sha3_generic_keccak_absorb_final_c71(uu____2, ret); - size_t outlen = Eurydice_slice_len(out[0U], uint8_t); + Eurydice_slice buf[1U] = {data}; + libcrux_sha3_generic_keccak_absorb_block_80_c60(&s, buf, i0 * (size_t)136U); + } + size_t rem = data_len % (size_t)136U; + Eurydice_slice buf[1U] = {data}; + libcrux_sha3_generic_keccak_absorb_final_80_9e1(&s, buf, data_len - rem, rem); + size_t outlen = Eurydice_slice_len(out, uint8_t); size_t blocks = outlen / (size_t)136U; size_t last = outlen - outlen % (size_t)136U; if (blocks == (size_t)0U) { - libcrux_sha3_generic_keccak_squeeze_first_and_last_c50(&s, out); + libcrux_sha3_simd_portable_squeeze_13_5b(&s, out, (size_t)0U, outlen); } else { - Eurydice_slice_uint8_t_1size_t__x2 uu____4 = - libcrux_sha3_portable_keccak_split_at_mut_n_5a(out, (size_t)136U); - Eurydice_slice o0[1U]; - memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice o1[1U]; - memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block_840(&s, o0); - core_ops_range_Range_b3 iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter( - (CLITERAL(core_ops_range_Range_b3){.start = (size_t)1U, - .end = blocks}), - core_ops_range_Range_b3, core_ops_range_Range_b3); - while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( - &iter, size_t, Option_b3) - .tag == None) { - break; - } else { - Eurydice_slice_uint8_t_1size_t__x2 uu____5 = - libcrux_sha3_portable_keccak_split_at_mut_n_5a(o1, (size_t)136U); - Eurydice_slice o[1U]; - memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice orest[1U]; - memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block_fc0(&s, o); - memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); - } + libcrux_sha3_simd_portable_squeeze_13_5b(&s, out, (size_t)0U, (size_t)136U); + for (size_t i = (size_t)1U; i < blocks; i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_keccakf1600_80_04(&s); + libcrux_sha3_simd_portable_squeeze_13_5b(&s, out, i0 * (size_t)136U, + (size_t)136U); } if (last < outlen) { - libcrux_sha3_generic_keccak_squeeze_last_cf0(s, o1); + libcrux_sha3_generic_keccak_keccakf1600_80_04(&s); + libcrux_sha3_simd_portable_squeeze_13_5b(&s, out, last, outlen - last); } } } -/** -A monomorphic instance of libcrux_sha3.portable.keccakx1 -with const generics -- RATE= 136 -- DELIM= 31 -*/ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccakx1_ce1( - Eurydice_slice data[1U], Eurydice_slice out[1U]) { - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_data[1U]; - memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_keccak_e91(copy_of_data, out); -} - /** A portable SHAKE256 implementation. */ static KRML_MUSTINLINE void libcrux_sha3_portable_shake256( Eurydice_slice digest, Eurydice_slice data) { - Eurydice_slice buf0[1U] = {data}; - Eurydice_slice buf[1U] = {digest}; - libcrux_sha3_portable_keccakx1_ce1(buf0, buf); + libcrux_sha3_generic_keccak_portable_keccak1_ad0(data, digest); } -typedef libcrux_sha3_generic_keccak_KeccakState_48 +typedef libcrux_sha3_generic_keccak_KeccakState_17 libcrux_sha3_portable_KeccakState; /** Create a new SHAKE-128 state object. */ -static KRML_MUSTINLINE libcrux_sha3_generic_keccak_KeccakState_48 +static KRML_MUSTINLINE libcrux_sha3_generic_keccak_KeccakState_17 libcrux_sha3_portable_incremental_shake128_init(void) { - return libcrux_sha3_generic_keccak_new_1e_f4(); + return libcrux_sha3_generic_keccak_new_80_04(); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.load_block +A monomorphic instance of libcrux_sha3.simd.portable.load_block with const generics - RATE= 168 */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_2c1( - uint64_t (*s)[5U], Eurydice_slice blocks[1U]) { +static KRML_MUSTINLINE void libcrux_sha3_simd_portable_load_block_3a( + uint64_t *state, Eurydice_slice blocks, size_t start) { + uint64_t state_flat[25U] = {0U}; for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)8U; i++) { size_t i0 = i; + size_t offset = start + (size_t)8U * i0; uint8_t uu____0[8U]; - Result_56 dst; + Result_15 dst; Eurydice_slice_to_array2( &dst, - Eurydice_slice_subslice2(blocks[0U], (size_t)8U * i0, - (size_t)8U * i0 + (size_t)8U, uint8_t), - Eurydice_slice, uint8_t[8U]); - unwrap_41_ac(dst, uu____0); - size_t uu____1 = i0 / (size_t)5U; - size_t uu____2 = i0 % (size_t)5U; - s[uu____1][uu____2] = - s[uu____1][uu____2] ^ core_num__u64_9__from_le_bytes(uu____0); + Eurydice_slice_subslice3(blocks, offset, offset + (size_t)8U, + uint8_t *), + Eurydice_slice, uint8_t[8U], TryFromSliceError); + unwrap_26_68(dst, uu____0); + state_flat[i0] = core_num__u64__from_le_bytes(uu____0); + } + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)8U; i++) { + size_t i0 = i; + libcrux_sha3_traits_set_ij_04( + state, i0 / (size_t)5U, i0 % (size_t)5U, + libcrux_sha3_traits_get_ij_04(state, i0 / (size_t)5U, + i0 % (size_t)5U)[0U] ^ + state_flat[i0]); } } /** -A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full +A monomorphic instance of libcrux_sha3.simd.portable.load_last with const generics - RATE= 168 +- DELIMITER= 31 */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_df1( - uint64_t (*s)[5U], uint8_t blocks[1U][200U]) { - Eurydice_slice buf[1U] = { - Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t)}; - libcrux_sha3_portable_keccak_load_block_2c1(s, buf); +static KRML_MUSTINLINE void libcrux_sha3_simd_portable_load_last_c6( + uint64_t *state, Eurydice_slice blocks, size_t start, size_t len) { + uint8_t buffer[168U] = {0U}; + Eurydice_slice_copy( + Eurydice_array_to_subslice3(buffer, (size_t)0U, len, uint8_t *), + Eurydice_slice_subslice3(blocks, start, start + len, uint8_t *), uint8_t); + buffer[len] = 31U; + size_t uu____0 = (size_t)168U - (size_t)1U; + buffer[uu____0] = (uint32_t)buffer[uu____0] | 128U; + libcrux_sha3_simd_portable_load_block_3a( + state, Eurydice_array_to_slice((size_t)168U, buffer, uint8_t), + (size_t)0U); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::Absorb<1usize> for +libcrux_sha3::generic_keccak::KeccakState[core::marker::Sized, +libcrux_sha3::simd::portable::{libcrux_sha3::traits::KeccakItem<1usize> for +u64}]} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full_5a +A monomorphic instance of libcrux_sha3.simd.portable.load_last_a1 with const generics - RATE= 168 +- DELIMITER= 31 */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_5a_d21( - uint64_t (*a)[5U], uint8_t b[1U][200U]) { - uint64_t(*uu____0)[5U] = a; - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_b[1U][200U]; - memcpy(copy_of_b, b, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak_load_block_full_df1(uu____0, copy_of_b); +static inline void libcrux_sha3_simd_portable_load_last_a1_c6( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice *input, + size_t start, size_t len) { + libcrux_sha3_simd_portable_load_last_c6(self->st, input[0U], start, len); } /** -A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final +This function found in impl {libcrux_sha3::generic_keccak::KeccakState[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final_80 with types uint64_t with const generics - N= 1 - RATE= 168 - DELIM= 31 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_c72( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice last[1U]) { - size_t last_len = Eurydice_slice_len(last[0U], uint8_t); - uint8_t blocks[1U][200U] = {{0U}}; - for (size_t i = (size_t)0U; i < (size_t)1U; i++) { - size_t i0 = i; - if (last_len > (size_t)0U) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice2( - blocks[i0], (size_t)0U, last_len, uint8_t); - Eurydice_slice_copy(uu____0, last[i0], uint8_t); - } - blocks[i0][last_len] = 31U; - size_t uu____1 = i0; - size_t uu____2 = (size_t)168U - (size_t)1U; - blocks[uu____1][uu____2] = (uint32_t)blocks[uu____1][uu____2] | 128U; - } - uint64_t(*uu____3)[5U] = s->st; - uint8_t uu____4[1U][200U]; - memcpy(uu____4, blocks, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak_load_block_full_5a_d21(uu____3, uu____4); - libcrux_sha3_generic_keccak_keccakf1600_21(s); +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_80_9e2( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice *last, + size_t start, size_t len) { + libcrux_sha3_simd_portable_load_last_a1_c6(self, last, start, len); + libcrux_sha3_generic_keccak_keccakf1600_80_04(self); } /** @@ -3120,143 +3866,160 @@ static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_c72( */ static KRML_MUSTINLINE void libcrux_sha3_portable_incremental_shake128_absorb_final( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice data0) { - Eurydice_slice buf[1U] = {data0}; - libcrux_sha3_generic_keccak_absorb_final_c72(s, buf); + libcrux_sha3_generic_keccak_KeccakState_17 *s, Eurydice_slice data0) { + libcrux_sha3_generic_keccak_KeccakState_17 *uu____0 = s; + Eurydice_slice uu____1[1U] = {data0}; + libcrux_sha3_generic_keccak_absorb_final_80_9e2( + uu____0, uu____1, (size_t)0U, Eurydice_slice_len(data0, uint8_t)); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.store_block +A monomorphic instance of libcrux_sha3.simd.portable.store_block with const generics - RATE= 168 */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_581( - uint64_t (*s)[5U], Eurydice_slice out[1U]) { - for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)8U; i++) { +static KRML_MUSTINLINE void libcrux_sha3_simd_portable_store_block_3a( + uint64_t *s, Eurydice_slice out, size_t start, size_t len) { + size_t octets = len / (size_t)8U; + for (size_t i = (size_t)0U; i < octets; i++) { size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_slice_subslice2( - out[0U], (size_t)8U * i0, (size_t)8U * i0 + (size_t)8U, uint8_t); + Eurydice_slice uu____0 = Eurydice_slice_subslice3( + out, start + (size_t)8U * i0, start + (size_t)8U * i0 + (size_t)8U, + uint8_t *); uint8_t ret[8U]; - core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); + core_num__u64__to_le_bytes( + libcrux_sha3_traits_get_ij_04(s, i0 / (size_t)5U, i0 % (size_t)5U)[0U], + ret); Eurydice_slice_copy( uu____0, Eurydice_array_to_slice((size_t)8U, ret, uint8_t), uint8_t); } + size_t remaining = len % (size_t)8U; + if (remaining > (size_t)0U) { + Eurydice_slice uu____1 = Eurydice_slice_subslice3( + out, start + len - remaining, start + len, uint8_t *); + uint8_t ret[8U]; + core_num__u64__to_le_bytes( + libcrux_sha3_traits_get_ij_04(s, octets / (size_t)5U, + octets % (size_t)5U)[0U], + ret); + Eurydice_slice_copy( + uu____1, + Eurydice_array_to_subslice3(ret, (size_t)0U, remaining, uint8_t *), + uint8_t); + } } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::Squeeze1 for +libcrux_sha3::generic_keccak::KeccakState[core::marker::Sized, +libcrux_sha3::simd::portable::{libcrux_sha3::traits::KeccakItem<1usize> for +u64}]} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.store_block_5a +A monomorphic instance of libcrux_sha3.simd.portable.squeeze_13 with const generics - RATE= 168 */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_5a_591( - uint64_t (*a)[5U], Eurydice_slice b[1U]) { - libcrux_sha3_portable_keccak_store_block_581(a, b); +static inline void libcrux_sha3_simd_portable_squeeze_13_3a( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice out, + size_t start, size_t len) { + libcrux_sha3_simd_portable_store_block_3a(self->st, out, start, len); } /** -A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_next_block -with types uint64_t -with const generics -- N= 1 +This function found in impl {libcrux_sha3::generic_keccak::KeccakState[core::marker::Sized, +libcrux_sha3::simd::portable::{libcrux_sha3::traits::KeccakItem<1usize> for +u64}]} +*/ +/** +A monomorphic instance of +libcrux_sha3.generic_keccak.portable.squeeze_first_three_blocks_b4 with const +generics - RATE= 168 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_next_block_fc1( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_keccakf1600_21(s); - libcrux_sha3_portable_keccak_store_block_5a_591(s->st, out); +static KRML_MUSTINLINE void +libcrux_sha3_generic_keccak_portable_squeeze_first_three_blocks_b4_3a( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice out) { + libcrux_sha3_simd_portable_squeeze_13_3a(self, out, (size_t)0U, (size_t)168U); + libcrux_sha3_generic_keccak_keccakf1600_80_04(self); + libcrux_sha3_simd_portable_squeeze_13_3a(self, out, (size_t)168U, + (size_t)168U); + libcrux_sha3_generic_keccak_keccakf1600_80_04(self); + libcrux_sha3_simd_portable_squeeze_13_3a(self, out, (size_t)2U * (size_t)168U, + (size_t)168U); } /** - Squeeze another block + Squeeze three blocks */ static KRML_MUSTINLINE void -libcrux_sha3_portable_incremental_shake128_squeeze_next_block( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out0) { - Eurydice_slice buf[1U] = {out0}; - libcrux_sha3_generic_keccak_squeeze_next_block_fc1(s, buf); +libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks( + libcrux_sha3_generic_keccak_KeccakState_17 *s, Eurydice_slice out0) { + libcrux_sha3_generic_keccak_portable_squeeze_first_three_blocks_b4_3a(s, + out0); } /** -A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_block -with types uint64_t -with const generics -- N= 1 -- RATE= 168 +This function found in impl {libcrux_sha3::generic_keccak::KeccakState[core::marker::Sized, +libcrux_sha3::simd::portable::{libcrux_sha3::traits::KeccakItem<1usize> for +u64}]} */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_first_block_841( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { - libcrux_sha3_portable_keccak_store_block_5a_591(s->st, out); -} - /** -A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_three_blocks -with types uint64_t -with const generics -- N= 1 +A monomorphic instance of +libcrux_sha3.generic_keccak.portable.squeeze_next_block_b4 with const generics - RATE= 168 */ static KRML_MUSTINLINE void -libcrux_sha3_generic_keccak_squeeze_first_three_blocks_cc( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { - Eurydice_slice_uint8_t_1size_t__x2 uu____0 = - libcrux_sha3_portable_keccak_split_at_mut_n_5a(out, (size_t)168U); - Eurydice_slice o0[1U]; - memcpy(o0, uu____0.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice o10[1U]; - memcpy(o10, uu____0.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block_841(s, o0); - Eurydice_slice_uint8_t_1size_t__x2 uu____1 = - libcrux_sha3_portable_keccak_split_at_mut_n_5a(o10, (size_t)168U); - Eurydice_slice o1[1U]; - memcpy(o1, uu____1.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice o2[1U]; - memcpy(o2, uu____1.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block_fc1(s, o1); - libcrux_sha3_generic_keccak_squeeze_next_block_fc1(s, o2); +libcrux_sha3_generic_keccak_portable_squeeze_next_block_b4_3a( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice out, + size_t start) { + libcrux_sha3_generic_keccak_keccakf1600_80_04(self); + libcrux_sha3_simd_portable_squeeze_13_3a(self, out, start, (size_t)168U); } /** - Squeeze three blocks + Squeeze another block */ static KRML_MUSTINLINE void -libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out0) { - Eurydice_slice buf[1U] = {out0}; - libcrux_sha3_generic_keccak_squeeze_first_three_blocks_cc(s, buf); +libcrux_sha3_portable_incremental_shake128_squeeze_next_block( + libcrux_sha3_generic_keccak_KeccakState_17 *s, Eurydice_slice out0) { + libcrux_sha3_generic_keccak_portable_squeeze_next_block_b4_3a(s, out0, + (size_t)0U); } -#define libcrux_sha3_Sha224 0 -#define libcrux_sha3_Sha256 1 -#define libcrux_sha3_Sha384 2 -#define libcrux_sha3_Sha512 3 +#define libcrux_sha3_Algorithm_Sha224 1 +#define libcrux_sha3_Algorithm_Sha256 2 +#define libcrux_sha3_Algorithm_Sha384 3 +#define libcrux_sha3_Algorithm_Sha512 4 typedef uint8_t libcrux_sha3_Algorithm; +typedef uint8_t libcrux_sha3_Sha3_224Digest[28U]; + +typedef uint8_t libcrux_sha3_Sha3_256Digest[32U]; + +typedef uint8_t libcrux_sha3_Sha3_384Digest[48U]; + +typedef uint8_t libcrux_sha3_Sha3_512Digest[64U]; + /** Returns the output size of a digest. */ static inline size_t libcrux_sha3_digest_size(libcrux_sha3_Algorithm mode) { - size_t uu____0; switch (mode) { - case libcrux_sha3_Sha224: { - uu____0 = (size_t)28U; + case libcrux_sha3_Algorithm_Sha224: { break; } - case libcrux_sha3_Sha256: { - uu____0 = (size_t)32U; - break; + case libcrux_sha3_Algorithm_Sha256: { + return (size_t)32U; } - case libcrux_sha3_Sha384: { - uu____0 = (size_t)48U; - break; + case libcrux_sha3_Algorithm_Sha384: { + return (size_t)48U; } - case libcrux_sha3_Sha512: { - uu____0 = (size_t)64U; - break; + case libcrux_sha3_Algorithm_Sha512: { + return (size_t)64U; } default: { KRML_HOST_EPRINTF("KaRaMeL incomplete match at %s:%d\n", __FILE__, @@ -3264,725 +4027,453 @@ static inline size_t libcrux_sha3_digest_size(libcrux_sha3_Algorithm mode) { KRML_HOST_EXIT(253U); } } - return uu____0; + return (size_t)28U; } /** -A monomorphic instance of libcrux_sha3.portable_keccak.load_block +A monomorphic instance of libcrux_sha3.simd.portable.load_block with const generics - RATE= 144 */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_2c2( - uint64_t (*s)[5U], Eurydice_slice blocks[1U]) { +static KRML_MUSTINLINE void libcrux_sha3_simd_portable_load_block_2c( + uint64_t *state, Eurydice_slice blocks, size_t start) { + uint64_t state_flat[25U] = {0U}; for (size_t i = (size_t)0U; i < (size_t)144U / (size_t)8U; i++) { size_t i0 = i; + size_t offset = start + (size_t)8U * i0; uint8_t uu____0[8U]; - Result_56 dst; + Result_15 dst; Eurydice_slice_to_array2( &dst, - Eurydice_slice_subslice2(blocks[0U], (size_t)8U * i0, - (size_t)8U * i0 + (size_t)8U, uint8_t), - Eurydice_slice, uint8_t[8U]); - unwrap_41_ac(dst, uu____0); - size_t uu____1 = i0 / (size_t)5U; - size_t uu____2 = i0 % (size_t)5U; - s[uu____1][uu____2] = - s[uu____1][uu____2] ^ core_num__u64_9__from_le_bytes(uu____0); + Eurydice_slice_subslice3(blocks, offset, offset + (size_t)8U, + uint8_t *), + Eurydice_slice, uint8_t[8U], TryFromSliceError); + unwrap_26_68(dst, uu____0); + state_flat[i0] = core_num__u64__from_le_bytes(uu____0); + } + for (size_t i = (size_t)0U; i < (size_t)144U / (size_t)8U; i++) { + size_t i0 = i; + libcrux_sha3_traits_set_ij_04( + state, i0 / (size_t)5U, i0 % (size_t)5U, + libcrux_sha3_traits_get_ij_04(state, i0 / (size_t)5U, + i0 % (size_t)5U)[0U] ^ + state_flat[i0]); } } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::Absorb<1usize> for +libcrux_sha3::generic_keccak::KeccakState[core::marker::Sized, +libcrux_sha3::simd::portable::{libcrux_sha3::traits::KeccakItem<1usize> for +u64}]} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.load_block_5a +A monomorphic instance of libcrux_sha3.simd.portable.load_block_a1 with const generics - RATE= 144 */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_5a_b81( - uint64_t (*a)[5U], Eurydice_slice b[1U]) { - uint64_t(*uu____0)[5U] = a; - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_b[1U]; - memcpy(copy_of_b, b, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak_load_block_2c2(uu____0, copy_of_b); +static inline void libcrux_sha3_simd_portable_load_block_a1_2c( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice *input, + size_t start) { + libcrux_sha3_simd_portable_load_block_2c(self->st, input[0U], start); } /** -A monomorphic instance of libcrux_sha3.generic_keccak.absorb_block +This function found in impl {libcrux_sha3::generic_keccak::KeccakState[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_block_80 with types uint64_t with const generics - N= 1 - RATE= 144 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_block_df1( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice blocks[1U]) { - uint64_t(*uu____0)[5U] = s->st; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak_load_block_5a_b81(uu____0, uu____1); - libcrux_sha3_generic_keccak_keccakf1600_21(s); +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_block_80_c61( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice *blocks, + size_t start) { + libcrux_sha3_simd_portable_load_block_a1_2c(self, blocks, start); + libcrux_sha3_generic_keccak_keccakf1600_80_04(self); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full +A monomorphic instance of libcrux_sha3.simd.portable.load_last with const generics - RATE= 144 +- DELIMITER= 6 */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_df2( - uint64_t (*s)[5U], uint8_t blocks[1U][200U]) { - Eurydice_slice buf[1U] = { - Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t)}; - libcrux_sha3_portable_keccak_load_block_2c2(s, buf); +static KRML_MUSTINLINE void libcrux_sha3_simd_portable_load_last_1e( + uint64_t *state, Eurydice_slice blocks, size_t start, size_t len) { + uint8_t buffer[144U] = {0U}; + Eurydice_slice_copy( + Eurydice_array_to_subslice3(buffer, (size_t)0U, len, uint8_t *), + Eurydice_slice_subslice3(blocks, start, start + len, uint8_t *), uint8_t); + buffer[len] = 6U; + size_t uu____0 = (size_t)144U - (size_t)1U; + buffer[uu____0] = (uint32_t)buffer[uu____0] | 128U; + libcrux_sha3_simd_portable_load_block_2c( + state, Eurydice_array_to_slice((size_t)144U, buffer, uint8_t), + (size_t)0U); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::Absorb<1usize> for +libcrux_sha3::generic_keccak::KeccakState[core::marker::Sized, +libcrux_sha3::simd::portable::{libcrux_sha3::traits::KeccakItem<1usize> for +u64}]} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full_5a +A monomorphic instance of libcrux_sha3.simd.portable.load_last_a1 with const generics - RATE= 144 +- DELIMITER= 6 */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_5a_d22( - uint64_t (*a)[5U], uint8_t b[1U][200U]) { - uint64_t(*uu____0)[5U] = a; - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_b[1U][200U]; - memcpy(copy_of_b, b, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak_load_block_full_df2(uu____0, copy_of_b); +static inline void libcrux_sha3_simd_portable_load_last_a1_1e( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice *input, + size_t start, size_t len) { + libcrux_sha3_simd_portable_load_last_1e(self->st, input[0U], start, len); } /** -A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final +This function found in impl {libcrux_sha3::generic_keccak::KeccakState[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final_80 with types uint64_t with const generics - N= 1 - RATE= 144 - DELIM= 6 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_c73( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice last[1U]) { - size_t last_len = Eurydice_slice_len(last[0U], uint8_t); - uint8_t blocks[1U][200U] = {{0U}}; - for (size_t i = (size_t)0U; i < (size_t)1U; i++) { - size_t i0 = i; - if (last_len > (size_t)0U) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice2( - blocks[i0], (size_t)0U, last_len, uint8_t); - Eurydice_slice_copy(uu____0, last[i0], uint8_t); - } - blocks[i0][last_len] = 6U; - size_t uu____1 = i0; - size_t uu____2 = (size_t)144U - (size_t)1U; - blocks[uu____1][uu____2] = (uint32_t)blocks[uu____1][uu____2] | 128U; - } - uint64_t(*uu____3)[5U] = s->st; - uint8_t uu____4[1U][200U]; - memcpy(uu____4, blocks, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak_load_block_full_5a_d22(uu____3, uu____4); - libcrux_sha3_generic_keccak_keccakf1600_21(s); +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_80_9e3( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice *last, + size_t start, size_t len) { + libcrux_sha3_simd_portable_load_last_a1_1e(self, last, start, len); + libcrux_sha3_generic_keccak_keccakf1600_80_04(self); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.store_block +A monomorphic instance of libcrux_sha3.simd.portable.store_block with const generics - RATE= 144 */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_582( - uint64_t (*s)[5U], Eurydice_slice out[1U]) { - for (size_t i = (size_t)0U; i < (size_t)144U / (size_t)8U; i++) { +static KRML_MUSTINLINE void libcrux_sha3_simd_portable_store_block_2c( + uint64_t *s, Eurydice_slice out, size_t start, size_t len) { + size_t octets = len / (size_t)8U; + for (size_t i = (size_t)0U; i < octets; i++) { size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_slice_subslice2( - out[0U], (size_t)8U * i0, (size_t)8U * i0 + (size_t)8U, uint8_t); + Eurydice_slice uu____0 = Eurydice_slice_subslice3( + out, start + (size_t)8U * i0, start + (size_t)8U * i0 + (size_t)8U, + uint8_t *); uint8_t ret[8U]; - core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); + core_num__u64__to_le_bytes( + libcrux_sha3_traits_get_ij_04(s, i0 / (size_t)5U, i0 % (size_t)5U)[0U], + ret); Eurydice_slice_copy( uu____0, Eurydice_array_to_slice((size_t)8U, ret, uint8_t), uint8_t); } -} - -/** -A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full -with const generics -- RATE= 144 -*/ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_full_2d1( - uint64_t (*s)[5U], uint8_t ret[1U][200U]) { - uint8_t out[200U] = {0U}; - Eurydice_slice buf[1U] = { - Eurydice_array_to_slice((size_t)200U, out, uint8_t)}; - libcrux_sha3_portable_keccak_store_block_582(s, buf); - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_out[200U]; - memcpy(copy_of_out, out, (size_t)200U * sizeof(uint8_t)); - memcpy(ret[0U], copy_of_out, (size_t)200U * sizeof(uint8_t)); -} - -/** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} -*/ -/** -A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full_5a -with const generics -- RATE= 144 -*/ -static KRML_MUSTINLINE void -libcrux_sha3_portable_keccak_store_block_full_5a_291(uint64_t (*a)[5U], - uint8_t ret[1U][200U]) { - libcrux_sha3_portable_keccak_store_block_full_2d1(a, ret); -} - -/** -A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_and_last -with types uint64_t -with const generics -- N= 1 -- RATE= 144 -*/ -static KRML_MUSTINLINE void -libcrux_sha3_generic_keccak_squeeze_first_and_last_c51( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak_store_block_full_5a_291(s->st, b); - for (size_t i = (size_t)0U; i < (size_t)1U; i++) { - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range_b3 lit; - lit.start = (size_t)0U; - lit.end = Eurydice_slice_len(out[i0], uint8_t); + size_t remaining = len % (size_t)8U; + if (remaining > (size_t)0U) { + Eurydice_slice uu____1 = Eurydice_slice_subslice3( + out, start + len - remaining, start + len, uint8_t *); + uint8_t ret[8U]; + core_num__u64__to_le_bytes( + libcrux_sha3_traits_get_ij_04(s, octets / (size_t)5U, + octets % (size_t)5U)[0U], + ret); Eurydice_slice_copy( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range_b3), + uu____1, + Eurydice_array_to_subslice3(ret, (size_t)0U, remaining, uint8_t *), uint8_t); } } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} -*/ -/** -A monomorphic instance of libcrux_sha3.portable_keccak.store_block_5a -with const generics -- RATE= 144 -*/ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_5a_592( - uint64_t (*a)[5U], Eurydice_slice b[1U]) { - libcrux_sha3_portable_keccak_store_block_582(a, b); -} - -/** -A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_block -with types uint64_t -with const generics -- N= 1 -- RATE= 144 -*/ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_first_block_842( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { - libcrux_sha3_portable_keccak_store_block_5a_592(s->st, out); -} - -/** -A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_next_block -with types uint64_t -with const generics -- N= 1 -- RATE= 144 +This function found in impl {libcrux_sha3::traits::Squeeze1 for +libcrux_sha3::generic_keccak::KeccakState[core::marker::Sized, +libcrux_sha3::simd::portable::{libcrux_sha3::traits::KeccakItem<1usize> for +u64}]} */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_next_block_fc2( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_keccakf1600_21(s); - libcrux_sha3_portable_keccak_store_block_5a_592(s->st, out); -} - /** -A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_last -with types uint64_t +A monomorphic instance of libcrux_sha3.simd.portable.squeeze_13 with const generics -- N= 1 - RATE= 144 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_last_cf1( - libcrux_sha3_generic_keccak_KeccakState_48 s, Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_keccakf1600_21(&s); - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak_store_block_full_5a_291(s.st, b); - for (size_t i = (size_t)0U; i < (size_t)1U; i++) { - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range_b3 lit; - lit.start = (size_t)0U; - lit.end = Eurydice_slice_len(out[i0], uint8_t); - Eurydice_slice_copy( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range_b3), - uint8_t); - } +static inline void libcrux_sha3_simd_portable_squeeze_13_2c( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice out, + size_t start, size_t len) { + libcrux_sha3_simd_portable_store_block_2c(self->st, out, start, len); } /** -A monomorphic instance of libcrux_sha3.generic_keccak.keccak -with types uint64_t +A monomorphic instance of libcrux_sha3.generic_keccak.portable.keccak1 with const generics -- N= 1 - RATE= 144 - DELIM= 6 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_keccak_e92( - Eurydice_slice data[1U], Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_KeccakState_48 s = - libcrux_sha3_generic_keccak_new_1e_f4(); - for (size_t i = (size_t)0U; - i < Eurydice_slice_len(data[0U], uint8_t) / (size_t)144U; i++) { +static inline void libcrux_sha3_generic_keccak_portable_keccak1_1e( + Eurydice_slice data, Eurydice_slice out) { + libcrux_sha3_generic_keccak_KeccakState_17 s = + libcrux_sha3_generic_keccak_new_80_04(); + size_t data_len = Eurydice_slice_len(data, uint8_t); + for (size_t i = (size_t)0U; i < data_len / (size_t)144U; i++) { size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState_48 *uu____0 = &s; - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_data[1U]; - memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak_slice_n_5a(copy_of_data, i0 * (size_t)144U, - (size_t)144U, ret); - libcrux_sha3_generic_keccak_absorb_block_df1(uu____0, ret); - } - size_t rem = Eurydice_slice_len(data[0U], uint8_t) % (size_t)144U; - libcrux_sha3_generic_keccak_KeccakState_48 *uu____2 = &s; - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_data[1U]; - memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak_slice_n_5a( - copy_of_data, Eurydice_slice_len(data[0U], uint8_t) - rem, rem, ret); - libcrux_sha3_generic_keccak_absorb_final_c73(uu____2, ret); - size_t outlen = Eurydice_slice_len(out[0U], uint8_t); + Eurydice_slice buf[1U] = {data}; + libcrux_sha3_generic_keccak_absorb_block_80_c61(&s, buf, i0 * (size_t)144U); + } + size_t rem = data_len % (size_t)144U; + Eurydice_slice buf[1U] = {data}; + libcrux_sha3_generic_keccak_absorb_final_80_9e3(&s, buf, data_len - rem, rem); + size_t outlen = Eurydice_slice_len(out, uint8_t); size_t blocks = outlen / (size_t)144U; size_t last = outlen - outlen % (size_t)144U; if (blocks == (size_t)0U) { - libcrux_sha3_generic_keccak_squeeze_first_and_last_c51(&s, out); + libcrux_sha3_simd_portable_squeeze_13_2c(&s, out, (size_t)0U, outlen); } else { - Eurydice_slice_uint8_t_1size_t__x2 uu____4 = - libcrux_sha3_portable_keccak_split_at_mut_n_5a(out, (size_t)144U); - Eurydice_slice o0[1U]; - memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice o1[1U]; - memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block_842(&s, o0); - core_ops_range_Range_b3 iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter( - (CLITERAL(core_ops_range_Range_b3){.start = (size_t)1U, - .end = blocks}), - core_ops_range_Range_b3, core_ops_range_Range_b3); - while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( - &iter, size_t, Option_b3) - .tag == None) { - break; - } else { - Eurydice_slice_uint8_t_1size_t__x2 uu____5 = - libcrux_sha3_portable_keccak_split_at_mut_n_5a(o1, (size_t)144U); - Eurydice_slice o[1U]; - memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice orest[1U]; - memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block_fc2(&s, o); - memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); - } + libcrux_sha3_simd_portable_squeeze_13_2c(&s, out, (size_t)0U, (size_t)144U); + for (size_t i = (size_t)1U; i < blocks; i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_keccakf1600_80_04(&s); + libcrux_sha3_simd_portable_squeeze_13_2c(&s, out, i0 * (size_t)144U, + (size_t)144U); } if (last < outlen) { - libcrux_sha3_generic_keccak_squeeze_last_cf1(s, o1); + libcrux_sha3_generic_keccak_keccakf1600_80_04(&s); + libcrux_sha3_simd_portable_squeeze_13_2c(&s, out, last, outlen - last); } } } -/** -A monomorphic instance of libcrux_sha3.portable.keccakx1 -with const generics -- RATE= 144 -- DELIM= 6 -*/ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccakx1_ce2( - Eurydice_slice data[1U], Eurydice_slice out[1U]) { - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_data[1U]; - memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_keccak_e92(copy_of_data, out); -} - /** A portable SHA3 224 implementation. */ static KRML_MUSTINLINE void libcrux_sha3_portable_sha224(Eurydice_slice digest, Eurydice_slice data) { - Eurydice_slice buf0[1U] = {data}; - Eurydice_slice buf[1U] = {digest}; - libcrux_sha3_portable_keccakx1_ce2(buf0, buf); + libcrux_sha3_generic_keccak_portable_keccak1_1e(data, digest); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.load_block +A monomorphic instance of libcrux_sha3.simd.portable.load_block with const generics - RATE= 104 */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_2c3( - uint64_t (*s)[5U], Eurydice_slice blocks[1U]) { +static KRML_MUSTINLINE void libcrux_sha3_simd_portable_load_block_7a( + uint64_t *state, Eurydice_slice blocks, size_t start) { + uint64_t state_flat[25U] = {0U}; for (size_t i = (size_t)0U; i < (size_t)104U / (size_t)8U; i++) { size_t i0 = i; + size_t offset = start + (size_t)8U * i0; uint8_t uu____0[8U]; - Result_56 dst; + Result_15 dst; Eurydice_slice_to_array2( &dst, - Eurydice_slice_subslice2(blocks[0U], (size_t)8U * i0, - (size_t)8U * i0 + (size_t)8U, uint8_t), - Eurydice_slice, uint8_t[8U]); - unwrap_41_ac(dst, uu____0); - size_t uu____1 = i0 / (size_t)5U; - size_t uu____2 = i0 % (size_t)5U; - s[uu____1][uu____2] = - s[uu____1][uu____2] ^ core_num__u64_9__from_le_bytes(uu____0); + Eurydice_slice_subslice3(blocks, offset, offset + (size_t)8U, + uint8_t *), + Eurydice_slice, uint8_t[8U], TryFromSliceError); + unwrap_26_68(dst, uu____0); + state_flat[i0] = core_num__u64__from_le_bytes(uu____0); + } + for (size_t i = (size_t)0U; i < (size_t)104U / (size_t)8U; i++) { + size_t i0 = i; + libcrux_sha3_traits_set_ij_04( + state, i0 / (size_t)5U, i0 % (size_t)5U, + libcrux_sha3_traits_get_ij_04(state, i0 / (size_t)5U, + i0 % (size_t)5U)[0U] ^ + state_flat[i0]); } } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::Absorb<1usize> for +libcrux_sha3::generic_keccak::KeccakState[core::marker::Sized, +libcrux_sha3::simd::portable::{libcrux_sha3::traits::KeccakItem<1usize> for +u64}]} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.load_block_5a +A monomorphic instance of libcrux_sha3.simd.portable.load_block_a1 with const generics - RATE= 104 */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_5a_b82( - uint64_t (*a)[5U], Eurydice_slice b[1U]) { - uint64_t(*uu____0)[5U] = a; - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_b[1U]; - memcpy(copy_of_b, b, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak_load_block_2c3(uu____0, copy_of_b); +static inline void libcrux_sha3_simd_portable_load_block_a1_7a( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice *input, + size_t start) { + libcrux_sha3_simd_portable_load_block_7a(self->st, input[0U], start); } /** -A monomorphic instance of libcrux_sha3.generic_keccak.absorb_block +This function found in impl {libcrux_sha3::generic_keccak::KeccakState[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_block_80 with types uint64_t with const generics - N= 1 - RATE= 104 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_block_df2( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice blocks[1U]) { - uint64_t(*uu____0)[5U] = s->st; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak_load_block_5a_b82(uu____0, uu____1); - libcrux_sha3_generic_keccak_keccakf1600_21(s); +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_block_80_c62( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice *blocks, + size_t start) { + libcrux_sha3_simd_portable_load_block_a1_7a(self, blocks, start); + libcrux_sha3_generic_keccak_keccakf1600_80_04(self); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full +A monomorphic instance of libcrux_sha3.simd.portable.load_last with const generics - RATE= 104 +- DELIMITER= 6 */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_df3( - uint64_t (*s)[5U], uint8_t blocks[1U][200U]) { - Eurydice_slice buf[1U] = { - Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t)}; - libcrux_sha3_portable_keccak_load_block_2c3(s, buf); +static KRML_MUSTINLINE void libcrux_sha3_simd_portable_load_last_7c( + uint64_t *state, Eurydice_slice blocks, size_t start, size_t len) { + uint8_t buffer[104U] = {0U}; + Eurydice_slice_copy( + Eurydice_array_to_subslice3(buffer, (size_t)0U, len, uint8_t *), + Eurydice_slice_subslice3(blocks, start, start + len, uint8_t *), uint8_t); + buffer[len] = 6U; + size_t uu____0 = (size_t)104U - (size_t)1U; + buffer[uu____0] = (uint32_t)buffer[uu____0] | 128U; + libcrux_sha3_simd_portable_load_block_7a( + state, Eurydice_array_to_slice((size_t)104U, buffer, uint8_t), + (size_t)0U); } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::Absorb<1usize> for +libcrux_sha3::generic_keccak::KeccakState[core::marker::Sized, +libcrux_sha3::simd::portable::{libcrux_sha3::traits::KeccakItem<1usize> for +u64}]} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full_5a +A monomorphic instance of libcrux_sha3.simd.portable.load_last_a1 with const generics - RATE= 104 +- DELIMITER= 6 */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_5a_d23( - uint64_t (*a)[5U], uint8_t b[1U][200U]) { - uint64_t(*uu____0)[5U] = a; - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_b[1U][200U]; - memcpy(copy_of_b, b, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak_load_block_full_df3(uu____0, copy_of_b); +static inline void libcrux_sha3_simd_portable_load_last_a1_7c( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice *input, + size_t start, size_t len) { + libcrux_sha3_simd_portable_load_last_7c(self->st, input[0U], start, len); } /** -A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final +This function found in impl {libcrux_sha3::generic_keccak::KeccakState[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final_80 with types uint64_t with const generics - N= 1 - RATE= 104 - DELIM= 6 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_c74( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice last[1U]) { - size_t last_len = Eurydice_slice_len(last[0U], uint8_t); - uint8_t blocks[1U][200U] = {{0U}}; - for (size_t i = (size_t)0U; i < (size_t)1U; i++) { - size_t i0 = i; - if (last_len > (size_t)0U) { - Eurydice_slice uu____0 = Eurydice_array_to_subslice2( - blocks[i0], (size_t)0U, last_len, uint8_t); - Eurydice_slice_copy(uu____0, last[i0], uint8_t); - } - blocks[i0][last_len] = 6U; - size_t uu____1 = i0; - size_t uu____2 = (size_t)104U - (size_t)1U; - blocks[uu____1][uu____2] = (uint32_t)blocks[uu____1][uu____2] | 128U; - } - uint64_t(*uu____3)[5U] = s->st; - uint8_t uu____4[1U][200U]; - memcpy(uu____4, blocks, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak_load_block_full_5a_d23(uu____3, uu____4); - libcrux_sha3_generic_keccak_keccakf1600_21(s); +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_80_9e4( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice *last, + size_t start, size_t len) { + libcrux_sha3_simd_portable_load_last_a1_7c(self, last, start, len); + libcrux_sha3_generic_keccak_keccakf1600_80_04(self); } /** -A monomorphic instance of libcrux_sha3.portable_keccak.store_block +A monomorphic instance of libcrux_sha3.simd.portable.store_block with const generics - RATE= 104 */ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_583( - uint64_t (*s)[5U], Eurydice_slice out[1U]) { - for (size_t i = (size_t)0U; i < (size_t)104U / (size_t)8U; i++) { +static KRML_MUSTINLINE void libcrux_sha3_simd_portable_store_block_7a( + uint64_t *s, Eurydice_slice out, size_t start, size_t len) { + size_t octets = len / (size_t)8U; + for (size_t i = (size_t)0U; i < octets; i++) { size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_slice_subslice2( - out[0U], (size_t)8U * i0, (size_t)8U * i0 + (size_t)8U, uint8_t); + Eurydice_slice uu____0 = Eurydice_slice_subslice3( + out, start + (size_t)8U * i0, start + (size_t)8U * i0 + (size_t)8U, + uint8_t *); uint8_t ret[8U]; - core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); + core_num__u64__to_le_bytes( + libcrux_sha3_traits_get_ij_04(s, i0 / (size_t)5U, i0 % (size_t)5U)[0U], + ret); Eurydice_slice_copy( uu____0, Eurydice_array_to_slice((size_t)8U, ret, uint8_t), uint8_t); } -} - -/** -A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full -with const generics -- RATE= 104 -*/ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_full_2d2( - uint64_t (*s)[5U], uint8_t ret[1U][200U]) { - uint8_t out[200U] = {0U}; - Eurydice_slice buf[1U] = { - Eurydice_array_to_slice((size_t)200U, out, uint8_t)}; - libcrux_sha3_portable_keccak_store_block_583(s, buf); - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_out[200U]; - memcpy(copy_of_out, out, (size_t)200U * sizeof(uint8_t)); - memcpy(ret[0U], copy_of_out, (size_t)200U * sizeof(uint8_t)); -} - -/** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} -*/ -/** -A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full_5a -with const generics -- RATE= 104 -*/ -static KRML_MUSTINLINE void -libcrux_sha3_portable_keccak_store_block_full_5a_292(uint64_t (*a)[5U], - uint8_t ret[1U][200U]) { - libcrux_sha3_portable_keccak_store_block_full_2d2(a, ret); -} - -/** -A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_and_last -with types uint64_t -with const generics -- N= 1 -- RATE= 104 -*/ -static KRML_MUSTINLINE void -libcrux_sha3_generic_keccak_squeeze_first_and_last_c52( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak_store_block_full_5a_292(s->st, b); - for (size_t i = (size_t)0U; i < (size_t)1U; i++) { - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range_b3 lit; - lit.start = (size_t)0U; - lit.end = Eurydice_slice_len(out[i0], uint8_t); + size_t remaining = len % (size_t)8U; + if (remaining > (size_t)0U) { + Eurydice_slice uu____1 = Eurydice_slice_subslice3( + out, start + len - remaining, start + len, uint8_t *); + uint8_t ret[8U]; + core_num__u64__to_le_bytes( + libcrux_sha3_traits_get_ij_04(s, octets / (size_t)5U, + octets % (size_t)5U)[0U], + ret); Eurydice_slice_copy( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range_b3), + uu____1, + Eurydice_array_to_subslice3(ret, (size_t)0U, remaining, uint8_t *), uint8_t); } } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} -*/ -/** -A monomorphic instance of libcrux_sha3.portable_keccak.store_block_5a -with const generics -- RATE= 104 -*/ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_5a_593( - uint64_t (*a)[5U], Eurydice_slice b[1U]) { - libcrux_sha3_portable_keccak_store_block_583(a, b); -} - -/** -A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_block -with types uint64_t -with const generics -- N= 1 -- RATE= 104 -*/ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_first_block_843( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { - libcrux_sha3_portable_keccak_store_block_5a_593(s->st, out); -} - -/** -A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_next_block -with types uint64_t -with const generics -- N= 1 -- RATE= 104 +This function found in impl {libcrux_sha3::traits::Squeeze1 for +libcrux_sha3::generic_keccak::KeccakState[core::marker::Sized, +libcrux_sha3::simd::portable::{libcrux_sha3::traits::KeccakItem<1usize> for +u64}]} */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_next_block_fc3( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_keccakf1600_21(s); - libcrux_sha3_portable_keccak_store_block_5a_593(s->st, out); -} - /** -A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_last -with types uint64_t +A monomorphic instance of libcrux_sha3.simd.portable.squeeze_13 with const generics -- N= 1 - RATE= 104 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_last_cf2( - libcrux_sha3_generic_keccak_KeccakState_48 s, Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_keccakf1600_21(&s); - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak_store_block_full_5a_292(s.st, b); - for (size_t i = (size_t)0U; i < (size_t)1U; i++) { - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range_b3 lit; - lit.start = (size_t)0U; - lit.end = Eurydice_slice_len(out[i0], uint8_t); - Eurydice_slice_copy( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range_b3), - uint8_t); - } +static inline void libcrux_sha3_simd_portable_squeeze_13_7a( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice out, + size_t start, size_t len) { + libcrux_sha3_simd_portable_store_block_7a(self->st, out, start, len); } /** -A monomorphic instance of libcrux_sha3.generic_keccak.keccak -with types uint64_t +A monomorphic instance of libcrux_sha3.generic_keccak.portable.keccak1 with const generics -- N= 1 - RATE= 104 - DELIM= 6 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_keccak_e93( - Eurydice_slice data[1U], Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_KeccakState_48 s = - libcrux_sha3_generic_keccak_new_1e_f4(); - for (size_t i = (size_t)0U; - i < Eurydice_slice_len(data[0U], uint8_t) / (size_t)104U; i++) { +static inline void libcrux_sha3_generic_keccak_portable_keccak1_7c( + Eurydice_slice data, Eurydice_slice out) { + libcrux_sha3_generic_keccak_KeccakState_17 s = + libcrux_sha3_generic_keccak_new_80_04(); + size_t data_len = Eurydice_slice_len(data, uint8_t); + for (size_t i = (size_t)0U; i < data_len / (size_t)104U; i++) { size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState_48 *uu____0 = &s; - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_data[1U]; - memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak_slice_n_5a(copy_of_data, i0 * (size_t)104U, - (size_t)104U, ret); - libcrux_sha3_generic_keccak_absorb_block_df2(uu____0, ret); - } - size_t rem = Eurydice_slice_len(data[0U], uint8_t) % (size_t)104U; - libcrux_sha3_generic_keccak_KeccakState_48 *uu____2 = &s; - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_data[1U]; - memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak_slice_n_5a( - copy_of_data, Eurydice_slice_len(data[0U], uint8_t) - rem, rem, ret); - libcrux_sha3_generic_keccak_absorb_final_c74(uu____2, ret); - size_t outlen = Eurydice_slice_len(out[0U], uint8_t); + Eurydice_slice buf[1U] = {data}; + libcrux_sha3_generic_keccak_absorb_block_80_c62(&s, buf, i0 * (size_t)104U); + } + size_t rem = data_len % (size_t)104U; + Eurydice_slice buf[1U] = {data}; + libcrux_sha3_generic_keccak_absorb_final_80_9e4(&s, buf, data_len - rem, rem); + size_t outlen = Eurydice_slice_len(out, uint8_t); size_t blocks = outlen / (size_t)104U; size_t last = outlen - outlen % (size_t)104U; if (blocks == (size_t)0U) { - libcrux_sha3_generic_keccak_squeeze_first_and_last_c52(&s, out); + libcrux_sha3_simd_portable_squeeze_13_7a(&s, out, (size_t)0U, outlen); } else { - Eurydice_slice_uint8_t_1size_t__x2 uu____4 = - libcrux_sha3_portable_keccak_split_at_mut_n_5a(out, (size_t)104U); - Eurydice_slice o0[1U]; - memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice o1[1U]; - memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block_843(&s, o0); - core_ops_range_Range_b3 iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter( - (CLITERAL(core_ops_range_Range_b3){.start = (size_t)1U, - .end = blocks}), - core_ops_range_Range_b3, core_ops_range_Range_b3); - while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( - &iter, size_t, Option_b3) - .tag == None) { - break; - } else { - Eurydice_slice_uint8_t_1size_t__x2 uu____5 = - libcrux_sha3_portable_keccak_split_at_mut_n_5a(o1, (size_t)104U); - Eurydice_slice o[1U]; - memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice orest[1U]; - memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block_fc3(&s, o); - memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); - } + libcrux_sha3_simd_portable_squeeze_13_7a(&s, out, (size_t)0U, (size_t)104U); + for (size_t i = (size_t)1U; i < blocks; i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_keccakf1600_80_04(&s); + libcrux_sha3_simd_portable_squeeze_13_7a(&s, out, i0 * (size_t)104U, + (size_t)104U); } if (last < outlen) { - libcrux_sha3_generic_keccak_squeeze_last_cf2(s, o1); + libcrux_sha3_generic_keccak_keccakf1600_80_04(&s); + libcrux_sha3_simd_portable_squeeze_13_7a(&s, out, last, outlen - last); } } } -/** -A monomorphic instance of libcrux_sha3.portable.keccakx1 -with const generics -- RATE= 104 -- DELIM= 6 -*/ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccakx1_ce3( - Eurydice_slice data[1U], Eurydice_slice out[1U]) { - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_data[1U]; - memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_keccak_e93(copy_of_data, out); -} - /** A portable SHA3 384 implementation. */ static KRML_MUSTINLINE void libcrux_sha3_portable_sha384(Eurydice_slice digest, Eurydice_slice data) { - Eurydice_slice buf0[1U] = {data}; - Eurydice_slice buf[1U] = {digest}; - libcrux_sha3_portable_keccakx1_ce3(buf0, buf); + libcrux_sha3_generic_keccak_portable_keccak1_7c(data, digest); } /** @@ -3991,16 +4482,15 @@ static KRML_MUSTINLINE void libcrux_sha3_portable_sha384(Eurydice_slice digest, Preconditions: - `digest.len() == 28` */ -static KRML_MUSTINLINE void libcrux_sha3_sha224_ema(Eurydice_slice digest, - Eurydice_slice payload) { +static inline void libcrux_sha3_sha224_ema(Eurydice_slice digest, + Eurydice_slice payload) { libcrux_sha3_portable_sha224(digest, payload); } /** SHA3 224 */ -static KRML_MUSTINLINE void libcrux_sha3_sha224(Eurydice_slice data, - uint8_t ret[28U]) { +static inline void libcrux_sha3_sha224(Eurydice_slice data, uint8_t ret[28U]) { uint8_t out[28U] = {0U}; libcrux_sha3_sha224_ema(Eurydice_array_to_slice((size_t)28U, out, uint8_t), data); @@ -4010,16 +4500,15 @@ static KRML_MUSTINLINE void libcrux_sha3_sha224(Eurydice_slice data, /** SHA3 256 */ -static KRML_MUSTINLINE void libcrux_sha3_sha256_ema(Eurydice_slice digest, - Eurydice_slice payload) { +static inline void libcrux_sha3_sha256_ema(Eurydice_slice digest, + Eurydice_slice payload) { libcrux_sha3_portable_sha256(digest, payload); } /** SHA3 256 */ -static KRML_MUSTINLINE void libcrux_sha3_sha256(Eurydice_slice data, - uint8_t ret[32U]) { +static inline void libcrux_sha3_sha256(Eurydice_slice data, uint8_t ret[32U]) { uint8_t out[32U] = {0U}; libcrux_sha3_sha256_ema(Eurydice_array_to_slice((size_t)32U, out, uint8_t), data); @@ -4029,16 +4518,15 @@ static KRML_MUSTINLINE void libcrux_sha3_sha256(Eurydice_slice data, /** SHA3 384 */ -static KRML_MUSTINLINE void libcrux_sha3_sha384_ema(Eurydice_slice digest, - Eurydice_slice payload) { +static inline void libcrux_sha3_sha384_ema(Eurydice_slice digest, + Eurydice_slice payload) { libcrux_sha3_portable_sha384(digest, payload); } /** SHA3 384 */ -static KRML_MUSTINLINE void libcrux_sha3_sha384(Eurydice_slice data, - uint8_t ret[48U]) { +static inline void libcrux_sha3_sha384(Eurydice_slice data, uint8_t ret[48U]) { uint8_t out[48U] = {0U}; libcrux_sha3_sha384_ema(Eurydice_array_to_slice((size_t)48U, out, uint8_t), data); @@ -4048,16 +4536,15 @@ static KRML_MUSTINLINE void libcrux_sha3_sha384(Eurydice_slice data, /** SHA3 512 */ -static KRML_MUSTINLINE void libcrux_sha3_sha512_ema(Eurydice_slice digest, - Eurydice_slice payload) { +static inline void libcrux_sha3_sha512_ema(Eurydice_slice digest, + Eurydice_slice payload) { libcrux_sha3_portable_sha512(digest, payload); } /** SHA3 512 */ -static KRML_MUSTINLINE void libcrux_sha3_sha512(Eurydice_slice data, - uint8_t ret[64U]) { +static inline void libcrux_sha3_sha512(Eurydice_slice data, uint8_t ret[64U]) { uint8_t out[64U] = {0U}; libcrux_sha3_sha512_ema(Eurydice_array_to_slice((size_t)64U, out, uint8_t), data); @@ -4065,220 +4552,85 @@ static KRML_MUSTINLINE void libcrux_sha3_sha512(Eurydice_slice data, } /** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} -*/ -/** -A monomorphic instance of libcrux_sha3.portable_keccak.load_block_5a -with const generics -- RATE= 168 -*/ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_5a_b83( - uint64_t (*a)[5U], Eurydice_slice b[1U]) { - uint64_t(*uu____0)[5U] = a; - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_b[1U]; - memcpy(copy_of_b, b, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak_load_block_2c1(uu____0, copy_of_b); -} - -/** -A monomorphic instance of libcrux_sha3.generic_keccak.absorb_block -with types uint64_t -with const generics -- N= 1 -- RATE= 168 -*/ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_block_df3( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice blocks[1U]) { - uint64_t(*uu____0)[5U] = s->st; - Eurydice_slice uu____1[1U]; - memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak_load_block_5a_b83(uu____0, uu____1); - libcrux_sha3_generic_keccak_keccakf1600_21(s); -} - -/** -A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full -with const generics -- RATE= 168 -*/ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_full_2d3( - uint64_t (*s)[5U], uint8_t ret[1U][200U]) { - uint8_t out[200U] = {0U}; - Eurydice_slice buf[1U] = { - Eurydice_array_to_slice((size_t)200U, out, uint8_t)}; - libcrux_sha3_portable_keccak_store_block_581(s, buf); - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_out[200U]; - memcpy(copy_of_out, out, (size_t)200U * sizeof(uint8_t)); - memcpy(ret[0U], copy_of_out, (size_t)200U * sizeof(uint8_t)); -} - -/** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} +This function found in impl {libcrux_sha3::traits::Absorb<1usize> for +libcrux_sha3::generic_keccak::KeccakState[core::marker::Sized, +libcrux_sha3::simd::portable::{libcrux_sha3::traits::KeccakItem<1usize> for +u64}]} */ /** -A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full_5a +A monomorphic instance of libcrux_sha3.simd.portable.load_block_a1 with const generics - RATE= 168 */ -static KRML_MUSTINLINE void -libcrux_sha3_portable_keccak_store_block_full_5a_293(uint64_t (*a)[5U], - uint8_t ret[1U][200U]) { - libcrux_sha3_portable_keccak_store_block_full_2d3(a, ret); +static inline void libcrux_sha3_simd_portable_load_block_a1_3a( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice *input, + size_t start) { + libcrux_sha3_simd_portable_load_block_3a(self->st, input[0U], start); } /** -A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_and_last -with types uint64_t -with const generics -- N= 1 -- RATE= 168 +This function found in impl {libcrux_sha3::generic_keccak::KeccakState[TraitClause@0, TraitClause@1]} */ -static KRML_MUSTINLINE void -libcrux_sha3_generic_keccak_squeeze_first_and_last_c53( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak_store_block_full_5a_293(s->st, b); - for (size_t i = (size_t)0U; i < (size_t)1U; i++) { - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range_b3 lit; - lit.start = (size_t)0U; - lit.end = Eurydice_slice_len(out[i0], uint8_t); - Eurydice_slice_copy( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range_b3), - uint8_t); - } -} - /** -A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_last +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_block_80 with types uint64_t with const generics - N= 1 - RATE= 168 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_last_cf3( - libcrux_sha3_generic_keccak_KeccakState_48 s, Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_keccakf1600_21(&s); - uint8_t b[1U][200U]; - libcrux_sha3_portable_keccak_store_block_full_5a_293(s.st, b); - for (size_t i = (size_t)0U; i < (size_t)1U; i++) { - size_t i0 = i; - Eurydice_slice uu____0 = out[i0]; - uint8_t *uu____1 = b[i0]; - core_ops_range_Range_b3 lit; - lit.start = (size_t)0U; - lit.end = Eurydice_slice_len(out[i0], uint8_t); - Eurydice_slice_copy( - uu____0, - Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, - core_ops_range_Range_b3), - uint8_t); - } +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_block_80_c63( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice *blocks, + size_t start) { + libcrux_sha3_simd_portable_load_block_a1_3a(self, blocks, start); + libcrux_sha3_generic_keccak_keccakf1600_80_04(self); } /** -A monomorphic instance of libcrux_sha3.generic_keccak.keccak -with types uint64_t +A monomorphic instance of libcrux_sha3.generic_keccak.portable.keccak1 with const generics -- N= 1 - RATE= 168 - DELIM= 31 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_keccak_e94( - Eurydice_slice data[1U], Eurydice_slice out[1U]) { - libcrux_sha3_generic_keccak_KeccakState_48 s = - libcrux_sha3_generic_keccak_new_1e_f4(); - for (size_t i = (size_t)0U; - i < Eurydice_slice_len(data[0U], uint8_t) / (size_t)168U; i++) { +static inline void libcrux_sha3_generic_keccak_portable_keccak1_c6( + Eurydice_slice data, Eurydice_slice out) { + libcrux_sha3_generic_keccak_KeccakState_17 s = + libcrux_sha3_generic_keccak_new_80_04(); + size_t data_len = Eurydice_slice_len(data, uint8_t); + for (size_t i = (size_t)0U; i < data_len / (size_t)168U; i++) { size_t i0 = i; - libcrux_sha3_generic_keccak_KeccakState_48 *uu____0 = &s; - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_data[1U]; - memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak_slice_n_5a(copy_of_data, i0 * (size_t)168U, - (size_t)168U, ret); - libcrux_sha3_generic_keccak_absorb_block_df3(uu____0, ret); - } - size_t rem = Eurydice_slice_len(data[0U], uint8_t) % (size_t)168U; - libcrux_sha3_generic_keccak_KeccakState_48 *uu____2 = &s; - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_data[1U]; - memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak_slice_n_5a( - copy_of_data, Eurydice_slice_len(data[0U], uint8_t) - rem, rem, ret); - libcrux_sha3_generic_keccak_absorb_final_c72(uu____2, ret); - size_t outlen = Eurydice_slice_len(out[0U], uint8_t); + Eurydice_slice buf[1U] = {data}; + libcrux_sha3_generic_keccak_absorb_block_80_c63(&s, buf, i0 * (size_t)168U); + } + size_t rem = data_len % (size_t)168U; + Eurydice_slice buf[1U] = {data}; + libcrux_sha3_generic_keccak_absorb_final_80_9e2(&s, buf, data_len - rem, rem); + size_t outlen = Eurydice_slice_len(out, uint8_t); size_t blocks = outlen / (size_t)168U; size_t last = outlen - outlen % (size_t)168U; if (blocks == (size_t)0U) { - libcrux_sha3_generic_keccak_squeeze_first_and_last_c53(&s, out); + libcrux_sha3_simd_portable_squeeze_13_3a(&s, out, (size_t)0U, outlen); } else { - Eurydice_slice_uint8_t_1size_t__x2 uu____4 = - libcrux_sha3_portable_keccak_split_at_mut_n_5a(out, (size_t)168U); - Eurydice_slice o0[1U]; - memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice o1[1U]; - memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block_841(&s, o0); - core_ops_range_Range_b3 iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter( - (CLITERAL(core_ops_range_Range_b3){.start = (size_t)1U, - .end = blocks}), - core_ops_range_Range_b3, core_ops_range_Range_b3); - while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( - &iter, size_t, Option_b3) - .tag == None) { - break; - } else { - Eurydice_slice_uint8_t_1size_t__x2 uu____5 = - libcrux_sha3_portable_keccak_split_at_mut_n_5a(o1, (size_t)168U); - Eurydice_slice o[1U]; - memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice orest[1U]; - memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block_fc1(&s, o); - memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); - } + libcrux_sha3_simd_portable_squeeze_13_3a(&s, out, (size_t)0U, (size_t)168U); + for (size_t i = (size_t)1U; i < blocks; i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_keccakf1600_80_04(&s); + libcrux_sha3_simd_portable_squeeze_13_3a(&s, out, i0 * (size_t)168U, + (size_t)168U); } if (last < outlen) { - libcrux_sha3_generic_keccak_squeeze_last_cf3(s, o1); + libcrux_sha3_generic_keccak_keccakf1600_80_04(&s); + libcrux_sha3_simd_portable_squeeze_13_3a(&s, out, last, outlen - last); } } } -/** -A monomorphic instance of libcrux_sha3.portable.keccakx1 -with const generics -- RATE= 168 -- DELIM= 31 -*/ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccakx1_ce4( - Eurydice_slice data[1U], Eurydice_slice out[1U]) { - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_data[1U]; - memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_keccak_e94(copy_of_data, out); -} - /** A portable SHAKE128 implementation. */ static KRML_MUSTINLINE void libcrux_sha3_portable_shake128( Eurydice_slice digest, Eurydice_slice data) { - Eurydice_slice buf0[1U] = {data}; - Eurydice_slice buf[1U] = {digest}; - libcrux_sha3_portable_keccakx1_ce4(buf0, buf); + libcrux_sha3_generic_keccak_portable_keccak1_c6(data, digest); } /** @@ -4286,8 +4638,8 @@ static KRML_MUSTINLINE void libcrux_sha3_portable_shake128( Writes `out.len()` bytes. */ -static KRML_MUSTINLINE void libcrux_sha3_shake128_ema(Eurydice_slice out, - Eurydice_slice data) { +static inline void libcrux_sha3_shake128_ema(Eurydice_slice out, + Eurydice_slice data) { libcrux_sha3_portable_shake128(out, data); } @@ -4296,208 +4648,113 @@ static KRML_MUSTINLINE void libcrux_sha3_shake128_ema(Eurydice_slice out, Writes `out.len()` bytes. */ -static KRML_MUSTINLINE void libcrux_sha3_shake256_ema(Eurydice_slice out, - Eurydice_slice data) { +static inline void libcrux_sha3_shake256_ema(Eurydice_slice out, + Eurydice_slice data) { libcrux_sha3_portable_shake256(out, data); } -static const size_t libcrux_sha3_generic_keccak__PI[24U] = { - (size_t)6U, (size_t)12U, (size_t)18U, (size_t)24U, (size_t)3U, - (size_t)9U, (size_t)10U, (size_t)16U, (size_t)22U, (size_t)1U, - (size_t)7U, (size_t)13U, (size_t)19U, (size_t)20U, (size_t)4U, - (size_t)5U, (size_t)11U, (size_t)17U, (size_t)23U, (size_t)2U, - (size_t)8U, (size_t)14U, (size_t)15U, (size_t)21U}; - -static const size_t libcrux_sha3_generic_keccak__ROTC[24U] = { - (size_t)1U, (size_t)62U, (size_t)28U, (size_t)27U, (size_t)36U, - (size_t)44U, (size_t)6U, (size_t)55U, (size_t)20U, (size_t)3U, - (size_t)10U, (size_t)43U, (size_t)25U, (size_t)39U, (size_t)41U, - (size_t)45U, (size_t)15U, (size_t)21U, (size_t)8U, (size_t)18U, - (size_t)2U, (size_t)61U, (size_t)56U, (size_t)14U}; - /** - A portable SHA3 224 implementation. +This function found in impl {libcrux_sha3::generic_keccak::KeccakState[core::marker::Sized, +libcrux_sha3::simd::portable::{libcrux_sha3::traits::KeccakItem<1usize> for +u64}]} +*/ +/** +A monomorphic instance of +libcrux_sha3.generic_keccak.portable.squeeze_first_five_blocks_b4 with const +generics +- RATE= 168 */ -static KRML_MUSTINLINE void libcrux_sha3_neon_sha224(Eurydice_slice digest, - Eurydice_slice data) { - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); +static KRML_MUSTINLINE void +libcrux_sha3_generic_keccak_portable_squeeze_first_five_blocks_b4_3a( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice out) { + libcrux_sha3_simd_portable_squeeze_13_3a(self, out, (size_t)0U, (size_t)168U); + libcrux_sha3_generic_keccak_keccakf1600_80_04(self); + libcrux_sha3_simd_portable_squeeze_13_3a(self, out, (size_t)168U, + (size_t)168U); + libcrux_sha3_generic_keccak_keccakf1600_80_04(self); + libcrux_sha3_simd_portable_squeeze_13_3a(self, out, (size_t)2U * (size_t)168U, + (size_t)168U); + libcrux_sha3_generic_keccak_keccakf1600_80_04(self); + libcrux_sha3_simd_portable_squeeze_13_3a(self, out, (size_t)3U * (size_t)168U, + (size_t)168U); + libcrux_sha3_generic_keccak_keccakf1600_80_04(self); + libcrux_sha3_simd_portable_squeeze_13_3a(self, out, (size_t)4U * (size_t)168U, + (size_t)168U); } /** - A portable SHA3 256 implementation. + Squeeze five blocks */ -static KRML_MUSTINLINE void libcrux_sha3_neon_sha256(Eurydice_slice digest, - Eurydice_slice data) { - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); +static KRML_MUSTINLINE void +libcrux_sha3_portable_incremental_shake128_squeeze_first_five_blocks( + libcrux_sha3_generic_keccak_KeccakState_17 *s, Eurydice_slice out0) { + libcrux_sha3_generic_keccak_portable_squeeze_first_five_blocks_b4_3a(s, out0); } /** - A portable SHA3 384 implementation. + Absorb some data for SHAKE-256 for the last time */ -static KRML_MUSTINLINE void libcrux_sha3_neon_sha384(Eurydice_slice digest, - Eurydice_slice data) { - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); +static KRML_MUSTINLINE void +libcrux_sha3_portable_incremental_shake256_absorb_final( + libcrux_sha3_generic_keccak_KeccakState_17 *s, Eurydice_slice data) { + libcrux_sha3_generic_keccak_KeccakState_17 *uu____0 = s; + Eurydice_slice uu____1[1U] = {data}; + libcrux_sha3_generic_keccak_absorb_final_80_9e1( + uu____0, uu____1, (size_t)0U, Eurydice_slice_len(data, uint8_t)); } /** - A portable SHA3 512 implementation. + Create a new SHAKE-256 state object. */ -static KRML_MUSTINLINE void libcrux_sha3_neon_sha512(Eurydice_slice digest, - Eurydice_slice data) { - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); +static KRML_MUSTINLINE libcrux_sha3_generic_keccak_KeccakState_17 +libcrux_sha3_portable_incremental_shake256_init(void) { + return libcrux_sha3_generic_keccak_new_80_04(); } /** - Run SHAKE256 on both inputs in parallel. - - Writes the two results into `out0` and `out1` -*/ -static KRML_MUSTINLINE void libcrux_sha3_neon_x2_shake256(Eurydice_slice input0, - Eurydice_slice input1, - Eurydice_slice out0, - Eurydice_slice out1) { - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); -} - -typedef struct libcrux_sha3_neon_x2_incremental_KeccakState_s { - libcrux_sha3_generic_keccak_KeccakState_48 state[2U]; -} libcrux_sha3_neon_x2_incremental_KeccakState; - -/** - Initialise the `KeccakState2`. -*/ -static KRML_MUSTINLINE libcrux_sha3_neon_x2_incremental_KeccakState -libcrux_sha3_neon_x2_incremental_shake128_init(void) { - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); -} - -/** - Shake128 absorb `data0` and `data1` in the [`KeccakState`] `s`. -*/ -static KRML_MUSTINLINE void -libcrux_sha3_neon_x2_incremental_shake128_absorb_final( - libcrux_sha3_neon_x2_incremental_KeccakState *s, Eurydice_slice data0, - Eurydice_slice data1) { - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); -} - -/** - Squeeze 2 times the first three blocks in parallel in the - [`KeccakState`] and return the output in `out0` and `out1`. -*/ -static KRML_MUSTINLINE void -libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( - libcrux_sha3_neon_x2_incremental_KeccakState *s, Eurydice_slice out0, - Eurydice_slice out1) { - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); -} - -/** - Squeeze 2 times the next block in parallel in the - [`KeccakState`] and return the output in `out0` and `out1`. -*/ -static KRML_MUSTINLINE void -libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( - libcrux_sha3_neon_x2_incremental_KeccakState *s, Eurydice_slice out0, - Eurydice_slice out1) { - KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, - "panic!"); - KRML_HOST_EXIT(255U); -} - -/** -A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_five_blocks -with types uint64_t -with const generics -- N= 1 -- RATE= 168 +This function found in impl {libcrux_sha3::generic_keccak::KeccakState[core::marker::Sized, +libcrux_sha3::simd::portable::{libcrux_sha3::traits::KeccakItem<1usize> for +u64}]} */ -static KRML_MUSTINLINE void -libcrux_sha3_generic_keccak_squeeze_first_five_blocks_4f( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { - Eurydice_slice_uint8_t_1size_t__x2 uu____0 = - libcrux_sha3_portable_keccak_split_at_mut_n_5a(out, (size_t)168U); - Eurydice_slice o0[1U]; - memcpy(o0, uu____0.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice o10[1U]; - memcpy(o10, uu____0.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_first_block_841(s, o0); - Eurydice_slice_uint8_t_1size_t__x2 uu____1 = - libcrux_sha3_portable_keccak_split_at_mut_n_5a(o10, (size_t)168U); - Eurydice_slice o1[1U]; - memcpy(o1, uu____1.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice o20[1U]; - memcpy(o20, uu____1.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block_fc1(s, o1); - Eurydice_slice_uint8_t_1size_t__x2 uu____2 = - libcrux_sha3_portable_keccak_split_at_mut_n_5a(o20, (size_t)168U); - Eurydice_slice o2[1U]; - memcpy(o2, uu____2.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice o30[1U]; - memcpy(o30, uu____2.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block_fc1(s, o2); - Eurydice_slice_uint8_t_1size_t__x2 uu____3 = - libcrux_sha3_portable_keccak_split_at_mut_n_5a(o30, (size_t)168U); - Eurydice_slice o3[1U]; - memcpy(o3, uu____3.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice o4[1U]; - memcpy(o4, uu____3.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_squeeze_next_block_fc1(s, o3); - libcrux_sha3_generic_keccak_squeeze_next_block_fc1(s, o4); -} - /** - Squeeze five blocks +A monomorphic instance of +libcrux_sha3.generic_keccak.portable.squeeze_first_block_b4 with const generics +- RATE= 136 */ static KRML_MUSTINLINE void -libcrux_sha3_portable_incremental_shake128_squeeze_first_five_blocks( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out0) { - Eurydice_slice buf[1U] = {out0}; - libcrux_sha3_generic_keccak_squeeze_first_five_blocks_4f(s, buf); +libcrux_sha3_generic_keccak_portable_squeeze_first_block_b4_5b( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice out) { + libcrux_sha3_simd_portable_squeeze_13_5b(self, out, (size_t)0U, (size_t)136U); } /** - Absorb some data for SHAKE-256 for the last time + Squeeze the first SHAKE-256 block */ static KRML_MUSTINLINE void -libcrux_sha3_portable_incremental_shake256_absorb_final( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice data) { - Eurydice_slice buf[1U] = {data}; - libcrux_sha3_generic_keccak_absorb_final_c71(s, buf); +libcrux_sha3_portable_incremental_shake256_squeeze_first_block( + libcrux_sha3_generic_keccak_KeccakState_17 *s, Eurydice_slice out) { + libcrux_sha3_generic_keccak_portable_squeeze_first_block_b4_5b(s, out); } /** - Create a new SHAKE-256 state object. +This function found in impl {libcrux_sha3::generic_keccak::KeccakState[core::marker::Sized, +libcrux_sha3::simd::portable::{libcrux_sha3::traits::KeccakItem<1usize> for +u64}]} */ -static KRML_MUSTINLINE libcrux_sha3_generic_keccak_KeccakState_48 -libcrux_sha3_portable_incremental_shake256_init(void) { - return libcrux_sha3_generic_keccak_new_1e_f4(); -} - /** - Squeeze the first SHAKE-256 block +A monomorphic instance of +libcrux_sha3.generic_keccak.portable.squeeze_next_block_b4 with const generics +- RATE= 136 */ static KRML_MUSTINLINE void -libcrux_sha3_portable_incremental_shake256_squeeze_first_block( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out) { - Eurydice_slice buf[1U] = {out}; - libcrux_sha3_generic_keccak_squeeze_first_block_840(s, buf); +libcrux_sha3_generic_keccak_portable_squeeze_next_block_b4_5b( + libcrux_sha3_generic_keccak_KeccakState_17 *self, Eurydice_slice out, + size_t start) { + libcrux_sha3_generic_keccak_keccakf1600_80_04(self); + libcrux_sha3_simd_portable_squeeze_13_5b(self, out, start, (size_t)136U); } /** @@ -4505,51 +4762,43 @@ libcrux_sha3_portable_incremental_shake256_squeeze_first_block( */ static KRML_MUSTINLINE void libcrux_sha3_portable_incremental_shake256_squeeze_next_block( - libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out) { - Eurydice_slice buf[1U] = {out}; - libcrux_sha3_generic_keccak_squeeze_next_block_fc0(s, buf); + libcrux_sha3_generic_keccak_KeccakState_17 *s, Eurydice_slice out) { + libcrux_sha3_generic_keccak_portable_squeeze_next_block_b4_5b(s, out, + (size_t)0U); } /** -A monomorphic instance of libcrux_sha3.generic_keccak.KeccakXofState +A monomorphic instance of libcrux_sha3.generic_keccak.xof.KeccakXofState with types uint64_t with const generics - $1size_t - $136size_t */ -typedef struct libcrux_sha3_generic_keccak_KeccakXofState_4f_s { - libcrux_sha3_generic_keccak_KeccakState_48 inner; +typedef struct libcrux_sha3_generic_keccak_xof_KeccakXofState_e2_s { + libcrux_sha3_generic_keccak_KeccakState_17 inner; uint8_t buf[1U][136U]; size_t buf_len; bool sponge; -} libcrux_sha3_generic_keccak_KeccakXofState_4f; - -typedef libcrux_sha3_generic_keccak_KeccakXofState_4f - libcrux_sha3_portable_incremental_Shake256Absorb; +} libcrux_sha3_generic_keccak_xof_KeccakXofState_e2; -/** - Consume the internal buffer and the required amount of the input to pad to - `RATE`. +typedef libcrux_sha3_generic_keccak_xof_KeccakXofState_e2 + libcrux_sha3_portable_incremental_Shake256Xof; - Returns the `consumed` bytes from `inputs` if there's enough buffered - content to consume, and `0` otherwise. - If `consumed > 0` is returned, `self.buf` contains a full block to be - loaded. -*/ /** -This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} +This function found in impl +{libcrux_sha3::generic_keccak::xof::KeccakXofState[TraitClause@0, TraitClause@1]} */ /** -A monomorphic instance of libcrux_sha3.generic_keccak.fill_buffer_9d +A monomorphic instance of libcrux_sha3.generic_keccak.xof.fill_buffer_35 with types uint64_t with const generics - PARALLEL_LANES= 1 - RATE= 136 */ -static inline size_t libcrux_sha3_generic_keccak_fill_buffer_9d_b0( - libcrux_sha3_generic_keccak_KeccakXofState_4f *self, - Eurydice_slice inputs[1U]) { +static inline size_t libcrux_sha3_generic_keccak_xof_fill_buffer_35_c6( + libcrux_sha3_generic_keccak_xof_KeccakXofState_e2 *self, + Eurydice_slice *inputs) { size_t input_len = Eurydice_slice_len(inputs[0U], uint8_t); size_t consumed = (size_t)0U; if (self->buf_len > (size_t)0U) { @@ -4558,10 +4807,12 @@ static inline size_t libcrux_sha3_generic_keccak_fill_buffer_9d_b0( for (size_t i = (size_t)0U; i < (size_t)1U; i++) { size_t i0 = i; Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( - (size_t)136U, self->buf[i0], self->buf_len, uint8_t, size_t); + (size_t)136U, self->buf[i0], self->buf_len, uint8_t, size_t, + uint8_t[]); Eurydice_slice_copy( uu____0, - Eurydice_slice_subslice_to(inputs[i0], consumed, uint8_t, size_t), + Eurydice_slice_subslice_to(inputs[i0], consumed, uint8_t, size_t, + uint8_t[]), uint8_t); } self->buf_len = self->buf_len + consumed; @@ -4571,42 +4822,37 @@ static inline size_t libcrux_sha3_generic_keccak_fill_buffer_9d_b0( } /** -This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} +This function found in impl +{libcrux_sha3::generic_keccak::xof::KeccakXofState[TraitClause@0, TraitClause@1]} */ /** -A monomorphic instance of libcrux_sha3.generic_keccak.absorb_full_9d +A monomorphic instance of libcrux_sha3.generic_keccak.xof.absorb_full_35 with types uint64_t with const generics - PARALLEL_LANES= 1 - RATE= 136 */ -static inline size_t libcrux_sha3_generic_keccak_absorb_full_9d_f8( - libcrux_sha3_generic_keccak_KeccakXofState_4f *self, - Eurydice_slice inputs[1U]) { - libcrux_sha3_generic_keccak_KeccakXofState_4f *uu____0 = self; - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_inputs0[1U]; - memcpy(copy_of_inputs0, inputs, (size_t)1U * sizeof(Eurydice_slice)); +static inline size_t libcrux_sha3_generic_keccak_xof_absorb_full_35_c6( + libcrux_sha3_generic_keccak_xof_KeccakXofState_e2 *self, + Eurydice_slice *inputs) { size_t input_consumed = - libcrux_sha3_generic_keccak_fill_buffer_9d_b0(uu____0, copy_of_inputs0); + libcrux_sha3_generic_keccak_xof_fill_buffer_35_c6(self, inputs); if (input_consumed > (size_t)0U) { Eurydice_slice borrowed[1U]; for (size_t i = (size_t)0U; i < (size_t)1U; i++) { uint8_t buf[136U] = {0U}; - borrowed[i] = core_array___Array_T__N__23__as_slice( - (size_t)136U, buf, uint8_t, Eurydice_slice); + borrowed[i] = core_array___Array_T__N___as_slice((size_t)136U, buf, + uint8_t, Eurydice_slice); } for (size_t i = (size_t)0U; i < (size_t)1U; i++) { size_t i0 = i; borrowed[i0] = Eurydice_array_to_slice((size_t)136U, self->buf[i0], uint8_t); } - uint64_t(*uu____2)[5U] = self->inner.st; - Eurydice_slice uu____3[1U]; - memcpy(uu____3, borrowed, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak_load_block_5a_b80(uu____2, uu____3); - libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner); + libcrux_sha3_simd_portable_load_block_a1_5b(&self->inner, borrowed, + (size_t)0U); + libcrux_sha3_generic_keccak_keccakf1600_80_04(&self->inner); self->buf_len = (size_t)0U; } size_t input_to_consume = @@ -4615,63 +4861,41 @@ static inline size_t libcrux_sha3_generic_keccak_absorb_full_9d_f8( size_t remainder = input_to_consume % (size_t)136U; for (size_t i = (size_t)0U; i < num_blocks; i++) { size_t i0 = i; - uint64_t(*uu____4)[5U] = self->inner.st; - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_inputs[1U]; - memcpy(copy_of_inputs, inputs, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak_slice_n_5a( - copy_of_inputs, input_consumed + i0 * (size_t)136U, (size_t)136U, ret); - libcrux_sha3_portable_keccak_load_block_5a_b80(uu____4, ret); - libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner); + libcrux_sha3_simd_portable_load_block_a1_5b( + &self->inner, inputs, input_consumed + i0 * (size_t)136U); + libcrux_sha3_generic_keccak_keccakf1600_80_04(&self->inner); } return remainder; } /** - Absorb - - This function takes any number of bytes to absorb and buffers if it's not - enough. The function assumes that all input slices in `blocks` have the same - length. - - Only a multiple of `RATE` blocks are absorbed. - For the remaining bytes [`absorb_final`] needs to be called. - - This works best with relatively small `inputs`. -*/ -/** -This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} +This function found in impl +{libcrux_sha3::generic_keccak::xof::KeccakXofState[TraitClause@0, TraitClause@1]} */ /** -A monomorphic instance of libcrux_sha3.generic_keccak.absorb_9d +A monomorphic instance of libcrux_sha3.generic_keccak.xof.absorb_35 with types uint64_t with const generics - PARALLEL_LANES= 1 - RATE= 136 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_9d_7b( - libcrux_sha3_generic_keccak_KeccakXofState_4f *self, - Eurydice_slice inputs[1U]) { - libcrux_sha3_generic_keccak_KeccakXofState_4f *uu____0 = self; - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_inputs[1U]; - memcpy(copy_of_inputs, inputs, (size_t)1U * sizeof(Eurydice_slice)); +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_xof_absorb_35_c6( + libcrux_sha3_generic_keccak_xof_KeccakXofState_e2 *self, + Eurydice_slice *inputs) { size_t input_remainder_len = - libcrux_sha3_generic_keccak_absorb_full_9d_f8(uu____0, copy_of_inputs); + libcrux_sha3_generic_keccak_xof_absorb_full_35_c6(self, inputs); if (input_remainder_len > (size_t)0U) { size_t input_len = Eurydice_slice_len(inputs[0U], uint8_t); for (size_t i = (size_t)0U; i < (size_t)1U; i++) { size_t i0 = i; - Eurydice_slice uu____2 = Eurydice_array_to_subslice2( - self->buf[i0], self->buf_len, self->buf_len + input_remainder_len, - uint8_t); - Eurydice_slice_copy( - uu____2, - Eurydice_slice_subslice_from( - inputs[i0], input_len - input_remainder_len, uint8_t, size_t), - uint8_t); + Eurydice_slice_copy(Eurydice_array_to_subslice3( + self->buf[i0], self->buf_len, + self->buf_len + input_remainder_len, uint8_t *), + Eurydice_slice_subslice_from( + inputs[i0], input_len - input_remainder_len, + uint8_t, size_t, uint8_t[]), + uint8_t); } self->buf_len = self->buf_len + input_remainder_len; } @@ -4681,271 +4905,101 @@ static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_9d_7b( Shake256 absorb */ /** -This function found in impl -{(libcrux_sha3::portable::incremental::XofAbsorb<136: usize> for -libcrux_sha3::portable::incremental::Shake256Absorb)#2} +This function found in impl {libcrux_sha3::portable::incremental::Xof<136usize> +for libcrux_sha3::portable::incremental::Shake256Xof} */ -static inline void libcrux_sha3_portable_incremental_absorb_7d( - libcrux_sha3_generic_keccak_KeccakXofState_4f *self, Eurydice_slice input) { +static inline void libcrux_sha3_portable_incremental_absorb_42( + libcrux_sha3_generic_keccak_xof_KeccakXofState_e2 *self, + Eurydice_slice input) { Eurydice_slice buf[1U] = {input}; - libcrux_sha3_generic_keccak_absorb_9d_7b(self, buf); + libcrux_sha3_generic_keccak_xof_absorb_35_c6(self, buf); } -typedef libcrux_sha3_generic_keccak_KeccakXofState_4f - libcrux_sha3_portable_incremental_Shake256Squeeze; - -/** - Absorb a final block. - - The `inputs` block may be empty. Everything in the `inputs` block beyond - `RATE` bytes is ignored. -*/ /** -This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} +This function found in impl +{libcrux_sha3::generic_keccak::xof::KeccakXofState[TraitClause@0, TraitClause@1]} */ /** -A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final_9d +A monomorphic instance of libcrux_sha3.generic_keccak.xof.absorb_final_35 with types uint64_t with const generics - PARALLEL_LANES= 1 - RATE= 136 - DELIMITER= 31 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_9d_25( - libcrux_sha3_generic_keccak_KeccakXofState_4f *self, - Eurydice_slice inputs[1U]) { - libcrux_sha3_generic_keccak_KeccakXofState_4f *uu____0 = self; - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_inputs[1U]; - memcpy(copy_of_inputs, inputs, (size_t)1U * sizeof(Eurydice_slice)); - size_t input_remainder_len = - libcrux_sha3_generic_keccak_absorb_full_9d_f8(uu____0, copy_of_inputs); - size_t input_len = Eurydice_slice_len(inputs[0U], uint8_t); - uint8_t blocks[1U][200U] = {{0U}}; +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_xof_absorb_final_35_9e( + libcrux_sha3_generic_keccak_xof_KeccakXofState_e2 *self, + Eurydice_slice *inputs) { + libcrux_sha3_generic_keccak_xof_absorb_35_c6(self, inputs); + Eurydice_slice borrowed[1U]; + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + uint8_t buf[136U] = {0U}; + borrowed[i] = core_array___Array_T__N___as_slice((size_t)136U, buf, uint8_t, + Eurydice_slice); + } for (size_t i = (size_t)0U; i < (size_t)1U; i++) { size_t i0 = i; - if (self->buf_len > (size_t)0U) { - Eurydice_slice uu____2 = Eurydice_array_to_subslice2( - blocks[i0], (size_t)0U, self->buf_len, uint8_t); - Eurydice_slice_copy(uu____2, - Eurydice_array_to_subslice2(self->buf[i0], (size_t)0U, - self->buf_len, uint8_t), - uint8_t); - } - if (input_remainder_len > (size_t)0U) { - Eurydice_slice uu____3 = Eurydice_array_to_subslice2( - blocks[i0], self->buf_len, self->buf_len + input_remainder_len, - uint8_t); - Eurydice_slice_copy( - uu____3, - Eurydice_slice_subslice_from( - inputs[i0], input_len - input_remainder_len, uint8_t, size_t), - uint8_t); - } - blocks[i0][self->buf_len + input_remainder_len] = 31U; - size_t uu____4 = i0; - size_t uu____5 = (size_t)136U - (size_t)1U; - blocks[uu____4][uu____5] = (uint32_t)blocks[uu____4][uu____5] | 128U; + borrowed[i0] = + Eurydice_array_to_slice((size_t)136U, self->buf[i0], uint8_t); } - uint64_t(*uu____6)[5U] = self->inner.st; - uint8_t uu____7[1U][200U]; - memcpy(uu____7, blocks, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak_load_block_full_5a_d20(uu____6, uu____7); - libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner); + libcrux_sha3_simd_portable_load_last_a1_ad0(&self->inner, borrowed, + (size_t)0U, self->buf_len); + libcrux_sha3_generic_keccak_keccakf1600_80_04(&self->inner); } /** Shake256 absorb final */ /** -This function found in impl -{(libcrux_sha3::portable::incremental::XofAbsorb<136: usize> for -libcrux_sha3::portable::incremental::Shake256Absorb)#2} +This function found in impl {libcrux_sha3::portable::incremental::Xof<136usize> +for libcrux_sha3::portable::incremental::Shake256Xof} */ -static inline libcrux_sha3_generic_keccak_KeccakXofState_4f -libcrux_sha3_portable_incremental_absorb_final_7d( - libcrux_sha3_generic_keccak_KeccakXofState_4f self, Eurydice_slice input) { +static inline void libcrux_sha3_portable_incremental_absorb_final_42( + libcrux_sha3_generic_keccak_xof_KeccakXofState_e2 *self, + Eurydice_slice input) { Eurydice_slice buf[1U] = {input}; - libcrux_sha3_generic_keccak_absorb_final_9d_25(&self, buf); - return self; + libcrux_sha3_generic_keccak_xof_absorb_final_35_9e(self, buf); } /** - An all zero block -*/ -/** -This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} +This function found in impl +{libcrux_sha3::generic_keccak::xof::KeccakXofState[TraitClause@0, TraitClause@1]} */ /** -A monomorphic instance of libcrux_sha3.generic_keccak.zero_block_9d +A monomorphic instance of libcrux_sha3.generic_keccak.xof.zero_block_35 with types uint64_t with const generics - PARALLEL_LANES= 1 - RATE= 136 */ -static inline void libcrux_sha3_generic_keccak_zero_block_9d_e6( +static inline void libcrux_sha3_generic_keccak_xof_zero_block_35_c6( uint8_t ret[136U]) { - ret[0U] = 0U; - ret[1U] = 0U; - ret[2U] = 0U; - ret[3U] = 0U; - ret[4U] = 0U; - ret[5U] = 0U; - ret[6U] = 0U; - ret[7U] = 0U; - ret[8U] = 0U; - ret[9U] = 0U; - ret[10U] = 0U; - ret[11U] = 0U; - ret[12U] = 0U; - ret[13U] = 0U; - ret[14U] = 0U; - ret[15U] = 0U; - ret[16U] = 0U; - ret[17U] = 0U; - ret[18U] = 0U; - ret[19U] = 0U; - ret[20U] = 0U; - ret[21U] = 0U; - ret[22U] = 0U; - ret[23U] = 0U; - ret[24U] = 0U; - ret[25U] = 0U; - ret[26U] = 0U; - ret[27U] = 0U; - ret[28U] = 0U; - ret[29U] = 0U; - ret[30U] = 0U; - ret[31U] = 0U; - ret[32U] = 0U; - ret[33U] = 0U; - ret[34U] = 0U; - ret[35U] = 0U; - ret[36U] = 0U; - ret[37U] = 0U; - ret[38U] = 0U; - ret[39U] = 0U; - ret[40U] = 0U; - ret[41U] = 0U; - ret[42U] = 0U; - ret[43U] = 0U; - ret[44U] = 0U; - ret[45U] = 0U; - ret[46U] = 0U; - ret[47U] = 0U; - ret[48U] = 0U; - ret[49U] = 0U; - ret[50U] = 0U; - ret[51U] = 0U; - ret[52U] = 0U; - ret[53U] = 0U; - ret[54U] = 0U; - ret[55U] = 0U; - ret[56U] = 0U; - ret[57U] = 0U; - ret[58U] = 0U; - ret[59U] = 0U; - ret[60U] = 0U; - ret[61U] = 0U; - ret[62U] = 0U; - ret[63U] = 0U; - ret[64U] = 0U; - ret[65U] = 0U; - ret[66U] = 0U; - ret[67U] = 0U; - ret[68U] = 0U; - ret[69U] = 0U; - ret[70U] = 0U; - ret[71U] = 0U; - ret[72U] = 0U; - ret[73U] = 0U; - ret[74U] = 0U; - ret[75U] = 0U; - ret[76U] = 0U; - ret[77U] = 0U; - ret[78U] = 0U; - ret[79U] = 0U; - ret[80U] = 0U; - ret[81U] = 0U; - ret[82U] = 0U; - ret[83U] = 0U; - ret[84U] = 0U; - ret[85U] = 0U; - ret[86U] = 0U; - ret[87U] = 0U; - ret[88U] = 0U; - ret[89U] = 0U; - ret[90U] = 0U; - ret[91U] = 0U; - ret[92U] = 0U; - ret[93U] = 0U; - ret[94U] = 0U; - ret[95U] = 0U; - ret[96U] = 0U; - ret[97U] = 0U; - ret[98U] = 0U; - ret[99U] = 0U; - ret[100U] = 0U; - ret[101U] = 0U; - ret[102U] = 0U; - ret[103U] = 0U; - ret[104U] = 0U; - ret[105U] = 0U; - ret[106U] = 0U; - ret[107U] = 0U; - ret[108U] = 0U; - ret[109U] = 0U; - ret[110U] = 0U; - ret[111U] = 0U; - ret[112U] = 0U; - ret[113U] = 0U; - ret[114U] = 0U; - ret[115U] = 0U; - ret[116U] = 0U; - ret[117U] = 0U; - ret[118U] = 0U; - ret[119U] = 0U; - ret[120U] = 0U; - ret[121U] = 0U; - ret[122U] = 0U; - ret[123U] = 0U; - ret[124U] = 0U; - ret[125U] = 0U; - ret[126U] = 0U; - ret[127U] = 0U; - ret[128U] = 0U; - ret[129U] = 0U; - ret[130U] = 0U; - ret[131U] = 0U; - ret[132U] = 0U; - ret[133U] = 0U; - ret[134U] = 0U; - ret[135U] = 0U; -} - -/** - Generate a new keccak xof state. -*/ -/** -This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} -*/ -/** -A monomorphic instance of libcrux_sha3.generic_keccak.new_9d + memset(ret, 0U, 136U * sizeof(uint8_t)); +} + +/** +This function found in impl +{libcrux_sha3::generic_keccak::xof::KeccakXofState[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.xof.new_35 with types uint64_t with const generics - PARALLEL_LANES= 1 - RATE= 136 */ -static inline libcrux_sha3_generic_keccak_KeccakXofState_4f -libcrux_sha3_generic_keccak_new_9d_7e(void) { - libcrux_sha3_generic_keccak_KeccakXofState_4f lit; - lit.inner = libcrux_sha3_generic_keccak_new_1e_f4(); - uint8_t ret[136U]; - libcrux_sha3_generic_keccak_zero_block_9d_e6(ret); - memcpy(lit.buf[0U], ret, (size_t)136U * sizeof(uint8_t)); +static inline libcrux_sha3_generic_keccak_xof_KeccakXofState_e2 +libcrux_sha3_generic_keccak_xof_new_35_c6(void) { + libcrux_sha3_generic_keccak_xof_KeccakXofState_e2 lit; + lit.inner = libcrux_sha3_generic_keccak_new_80_04(); + uint8_t repeat_expression[1U][136U]; + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + libcrux_sha3_generic_keccak_xof_zero_block_35_c6(repeat_expression[i]); + } + memcpy(lit.buf, repeat_expression, (size_t)1U * sizeof(uint8_t[136U])); lit.buf_len = (size_t)0U; lit.sponge = false; return lit; @@ -4955,55 +5009,103 @@ libcrux_sha3_generic_keccak_new_9d_7e(void) { Shake256 new state */ /** +This function found in impl {libcrux_sha3::portable::incremental::Xof<136usize> +for libcrux_sha3::portable::incremental::Shake256Xof} +*/ +static inline libcrux_sha3_generic_keccak_xof_KeccakXofState_e2 +libcrux_sha3_portable_incremental_new_42(void) { + return libcrux_sha3_generic_keccak_xof_new_35_c6(); +} + +/** + Squeeze `N` x `LEN` bytes. Only `N = 1` for now. +*/ +/** This function found in impl -{(libcrux_sha3::portable::incremental::XofAbsorb<136: usize> for -libcrux_sha3::portable::incremental::Shake256Absorb)#2} +{libcrux_sha3::generic_keccak::xof::KeccakXofState[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.xof.squeeze_85 +with types uint64_t +with const generics +- RATE= 136 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_xof_squeeze_85_c7( + libcrux_sha3_generic_keccak_xof_KeccakXofState_e2 *self, + Eurydice_slice out) { + if (self->sponge) { + libcrux_sha3_generic_keccak_keccakf1600_80_04(&self->inner); + } + size_t out_len = Eurydice_slice_len(out, uint8_t); + if (out_len > (size_t)0U) { + if (out_len <= (size_t)136U) { + libcrux_sha3_simd_portable_squeeze_13_5b(&self->inner, out, (size_t)0U, + out_len); + } else { + size_t blocks = out_len / (size_t)136U; + for (size_t i = (size_t)0U; i < blocks; i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_keccakf1600_80_04(&self->inner); + libcrux_sha3_simd_portable_squeeze_13_5b( + &self->inner, out, i0 * (size_t)136U, (size_t)136U); + } + size_t remaining = out_len % (size_t)136U; + if (remaining > (size_t)0U) { + libcrux_sha3_generic_keccak_keccakf1600_80_04(&self->inner); + libcrux_sha3_simd_portable_squeeze_13_5b( + &self->inner, out, blocks * (size_t)136U, remaining); + } + } + self->sponge = true; + } +} + +/** + Shake256 squeeze */ -static inline libcrux_sha3_generic_keccak_KeccakXofState_4f -libcrux_sha3_portable_incremental_new_7d(void) { - return libcrux_sha3_generic_keccak_new_9d_7e(); +/** +This function found in impl {libcrux_sha3::portable::incremental::Xof<136usize> +for libcrux_sha3::portable::incremental::Shake256Xof} +*/ +static inline void libcrux_sha3_portable_incremental_squeeze_42( + libcrux_sha3_generic_keccak_xof_KeccakXofState_e2 *self, + Eurydice_slice out) { + libcrux_sha3_generic_keccak_xof_squeeze_85_c7(self, out); } /** -A monomorphic instance of libcrux_sha3.generic_keccak.KeccakXofState +A monomorphic instance of libcrux_sha3.generic_keccak.xof.KeccakXofState with types uint64_t with const generics - $1size_t - $168size_t */ -typedef struct libcrux_sha3_generic_keccak_KeccakXofState_78_s { - libcrux_sha3_generic_keccak_KeccakState_48 inner; +typedef struct libcrux_sha3_generic_keccak_xof_KeccakXofState_97_s { + libcrux_sha3_generic_keccak_KeccakState_17 inner; uint8_t buf[1U][168U]; size_t buf_len; bool sponge; -} libcrux_sha3_generic_keccak_KeccakXofState_78; - -typedef libcrux_sha3_generic_keccak_KeccakXofState_78 - libcrux_sha3_portable_incremental_Shake128Absorb; +} libcrux_sha3_generic_keccak_xof_KeccakXofState_97; -/** - Consume the internal buffer and the required amount of the input to pad to - `RATE`. +typedef libcrux_sha3_generic_keccak_xof_KeccakXofState_97 + libcrux_sha3_portable_incremental_Shake128Xof; - Returns the `consumed` bytes from `inputs` if there's enough buffered - content to consume, and `0` otherwise. - If `consumed > 0` is returned, `self.buf` contains a full block to be - loaded. -*/ /** -This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} +This function found in impl +{libcrux_sha3::generic_keccak::xof::KeccakXofState[TraitClause@0, TraitClause@1]} */ /** -A monomorphic instance of libcrux_sha3.generic_keccak.fill_buffer_9d +A monomorphic instance of libcrux_sha3.generic_keccak.xof.fill_buffer_35 with types uint64_t with const generics - PARALLEL_LANES= 1 - RATE= 168 */ -static inline size_t libcrux_sha3_generic_keccak_fill_buffer_9d_b00( - libcrux_sha3_generic_keccak_KeccakXofState_78 *self, - Eurydice_slice inputs[1U]) { +static inline size_t libcrux_sha3_generic_keccak_xof_fill_buffer_35_c60( + libcrux_sha3_generic_keccak_xof_KeccakXofState_97 *self, + Eurydice_slice *inputs) { size_t input_len = Eurydice_slice_len(inputs[0U], uint8_t); size_t consumed = (size_t)0U; if (self->buf_len > (size_t)0U) { @@ -5012,10 +5114,12 @@ static inline size_t libcrux_sha3_generic_keccak_fill_buffer_9d_b00( for (size_t i = (size_t)0U; i < (size_t)1U; i++) { size_t i0 = i; Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( - (size_t)168U, self->buf[i0], self->buf_len, uint8_t, size_t); + (size_t)168U, self->buf[i0], self->buf_len, uint8_t, size_t, + uint8_t[]); Eurydice_slice_copy( uu____0, - Eurydice_slice_subslice_to(inputs[i0], consumed, uint8_t, size_t), + Eurydice_slice_subslice_to(inputs[i0], consumed, uint8_t, size_t, + uint8_t[]), uint8_t); } self->buf_len = self->buf_len + consumed; @@ -5025,42 +5129,37 @@ static inline size_t libcrux_sha3_generic_keccak_fill_buffer_9d_b00( } /** -This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} +This function found in impl +{libcrux_sha3::generic_keccak::xof::KeccakXofState[TraitClause@0, TraitClause@1]} */ /** -A monomorphic instance of libcrux_sha3.generic_keccak.absorb_full_9d +A monomorphic instance of libcrux_sha3.generic_keccak.xof.absorb_full_35 with types uint64_t with const generics - PARALLEL_LANES= 1 - RATE= 168 */ -static inline size_t libcrux_sha3_generic_keccak_absorb_full_9d_f80( - libcrux_sha3_generic_keccak_KeccakXofState_78 *self, - Eurydice_slice inputs[1U]) { - libcrux_sha3_generic_keccak_KeccakXofState_78 *uu____0 = self; - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_inputs0[1U]; - memcpy(copy_of_inputs0, inputs, (size_t)1U * sizeof(Eurydice_slice)); +static inline size_t libcrux_sha3_generic_keccak_xof_absorb_full_35_c60( + libcrux_sha3_generic_keccak_xof_KeccakXofState_97 *self, + Eurydice_slice *inputs) { size_t input_consumed = - libcrux_sha3_generic_keccak_fill_buffer_9d_b00(uu____0, copy_of_inputs0); + libcrux_sha3_generic_keccak_xof_fill_buffer_35_c60(self, inputs); if (input_consumed > (size_t)0U) { Eurydice_slice borrowed[1U]; for (size_t i = (size_t)0U; i < (size_t)1U; i++) { uint8_t buf[168U] = {0U}; - borrowed[i] = core_array___Array_T__N__23__as_slice( - (size_t)168U, buf, uint8_t, Eurydice_slice); + borrowed[i] = core_array___Array_T__N___as_slice((size_t)168U, buf, + uint8_t, Eurydice_slice); } for (size_t i = (size_t)0U; i < (size_t)1U; i++) { size_t i0 = i; borrowed[i0] = Eurydice_array_to_slice((size_t)168U, self->buf[i0], uint8_t); } - uint64_t(*uu____2)[5U] = self->inner.st; - Eurydice_slice uu____3[1U]; - memcpy(uu____3, borrowed, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak_load_block_5a_b83(uu____2, uu____3); - libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner); + libcrux_sha3_simd_portable_load_block_a1_3a(&self->inner, borrowed, + (size_t)0U); + libcrux_sha3_generic_keccak_keccakf1600_80_04(&self->inner); self->buf_len = (size_t)0U; } size_t input_to_consume = @@ -5069,648 +5168,237 @@ static inline size_t libcrux_sha3_generic_keccak_absorb_full_9d_f80( size_t remainder = input_to_consume % (size_t)168U; for (size_t i = (size_t)0U; i < num_blocks; i++) { size_t i0 = i; - uint64_t(*uu____4)[5U] = self->inner.st; - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_inputs[1U]; - memcpy(copy_of_inputs, inputs, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice ret[1U]; - libcrux_sha3_portable_keccak_slice_n_5a( - copy_of_inputs, input_consumed + i0 * (size_t)168U, (size_t)168U, ret); - libcrux_sha3_portable_keccak_load_block_5a_b83(uu____4, ret); - libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner); + libcrux_sha3_simd_portable_load_block_a1_3a( + &self->inner, inputs, input_consumed + i0 * (size_t)168U); + libcrux_sha3_generic_keccak_keccakf1600_80_04(&self->inner); } return remainder; } /** - Absorb - - This function takes any number of bytes to absorb and buffers if it's not - enough. The function assumes that all input slices in `blocks` have the same - length. - - Only a multiple of `RATE` blocks are absorbed. - For the remaining bytes [`absorb_final`] needs to be called. - - This works best with relatively small `inputs`. -*/ -/** -This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} +This function found in impl +{libcrux_sha3::generic_keccak::xof::KeccakXofState[TraitClause@0, TraitClause@1]} */ /** -A monomorphic instance of libcrux_sha3.generic_keccak.absorb_9d +A monomorphic instance of libcrux_sha3.generic_keccak.xof.absorb_35 with types uint64_t with const generics - PARALLEL_LANES= 1 - RATE= 168 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_9d_7b0( - libcrux_sha3_generic_keccak_KeccakXofState_78 *self, - Eurydice_slice inputs[1U]) { - libcrux_sha3_generic_keccak_KeccakXofState_78 *uu____0 = self; - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_inputs[1U]; - memcpy(copy_of_inputs, inputs, (size_t)1U * sizeof(Eurydice_slice)); +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_xof_absorb_35_c60( + libcrux_sha3_generic_keccak_xof_KeccakXofState_97 *self, + Eurydice_slice *inputs) { size_t input_remainder_len = - libcrux_sha3_generic_keccak_absorb_full_9d_f80(uu____0, copy_of_inputs); + libcrux_sha3_generic_keccak_xof_absorb_full_35_c60(self, inputs); if (input_remainder_len > (size_t)0U) { size_t input_len = Eurydice_slice_len(inputs[0U], uint8_t); for (size_t i = (size_t)0U; i < (size_t)1U; i++) { size_t i0 = i; - Eurydice_slice uu____2 = Eurydice_array_to_subslice2( - self->buf[i0], self->buf_len, self->buf_len + input_remainder_len, - uint8_t); - Eurydice_slice_copy( - uu____2, - Eurydice_slice_subslice_from( - inputs[i0], input_len - input_remainder_len, uint8_t, size_t), - uint8_t); + Eurydice_slice_copy(Eurydice_array_to_subslice3( + self->buf[i0], self->buf_len, + self->buf_len + input_remainder_len, uint8_t *), + Eurydice_slice_subslice_from( + inputs[i0], input_len - input_remainder_len, + uint8_t, size_t, uint8_t[]), + uint8_t); } self->buf_len = self->buf_len + input_remainder_len; } } /** -This function found in impl -{(libcrux_sha3::portable::incremental::XofAbsorb<168: usize> for -libcrux_sha3::portable::incremental::Shake128Absorb)} +This function found in impl {libcrux_sha3::portable::incremental::Xof<168usize> +for libcrux_sha3::portable::incremental::Shake128Xof} */ -static inline void libcrux_sha3_portable_incremental_absorb_1c( - libcrux_sha3_generic_keccak_KeccakXofState_78 *self, Eurydice_slice input) { +static inline void libcrux_sha3_portable_incremental_absorb_26( + libcrux_sha3_generic_keccak_xof_KeccakXofState_97 *self, + Eurydice_slice input) { Eurydice_slice buf[1U] = {input}; - libcrux_sha3_generic_keccak_absorb_9d_7b0(self, buf); + libcrux_sha3_generic_keccak_xof_absorb_35_c60(self, buf); } -typedef libcrux_sha3_generic_keccak_KeccakXofState_78 - libcrux_sha3_portable_incremental_Shake128Squeeze; - /** - Absorb a final block. - - The `inputs` block may be empty. Everything in the `inputs` block beyond - `RATE` bytes is ignored. -*/ -/** -This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} +This function found in impl +{libcrux_sha3::generic_keccak::xof::KeccakXofState[TraitClause@0, TraitClause@1]} */ /** -A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final_9d +A monomorphic instance of libcrux_sha3.generic_keccak.xof.absorb_final_35 with types uint64_t with const generics - PARALLEL_LANES= 1 - RATE= 168 - DELIMITER= 31 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_9d_250( - libcrux_sha3_generic_keccak_KeccakXofState_78 *self, - Eurydice_slice inputs[1U]) { - libcrux_sha3_generic_keccak_KeccakXofState_78 *uu____0 = self; - /* Passing arrays by value in Rust generates a copy in C */ - Eurydice_slice copy_of_inputs[1U]; - memcpy(copy_of_inputs, inputs, (size_t)1U * sizeof(Eurydice_slice)); - size_t input_remainder_len = - libcrux_sha3_generic_keccak_absorb_full_9d_f80(uu____0, copy_of_inputs); - size_t input_len = Eurydice_slice_len(inputs[0U], uint8_t); - uint8_t blocks[1U][200U] = {{0U}}; +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_xof_absorb_final_35_9e0( + libcrux_sha3_generic_keccak_xof_KeccakXofState_97 *self, + Eurydice_slice *inputs) { + libcrux_sha3_generic_keccak_xof_absorb_35_c60(self, inputs); + Eurydice_slice borrowed[1U]; + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + uint8_t buf[168U] = {0U}; + borrowed[i] = core_array___Array_T__N___as_slice((size_t)168U, buf, uint8_t, + Eurydice_slice); + } for (size_t i = (size_t)0U; i < (size_t)1U; i++) { size_t i0 = i; - if (self->buf_len > (size_t)0U) { - Eurydice_slice uu____2 = Eurydice_array_to_subslice2( - blocks[i0], (size_t)0U, self->buf_len, uint8_t); - Eurydice_slice_copy(uu____2, - Eurydice_array_to_subslice2(self->buf[i0], (size_t)0U, - self->buf_len, uint8_t), - uint8_t); - } - if (input_remainder_len > (size_t)0U) { - Eurydice_slice uu____3 = Eurydice_array_to_subslice2( - blocks[i0], self->buf_len, self->buf_len + input_remainder_len, - uint8_t); - Eurydice_slice_copy( - uu____3, - Eurydice_slice_subslice_from( - inputs[i0], input_len - input_remainder_len, uint8_t, size_t), - uint8_t); - } - blocks[i0][self->buf_len + input_remainder_len] = 31U; - size_t uu____4 = i0; - size_t uu____5 = (size_t)168U - (size_t)1U; - blocks[uu____4][uu____5] = (uint32_t)blocks[uu____4][uu____5] | 128U; + borrowed[i0] = + Eurydice_array_to_slice((size_t)168U, self->buf[i0], uint8_t); } - uint64_t(*uu____6)[5U] = self->inner.st; - uint8_t uu____7[1U][200U]; - memcpy(uu____7, blocks, (size_t)1U * sizeof(uint8_t[200U])); - libcrux_sha3_portable_keccak_load_block_full_5a_d21(uu____6, uu____7); - libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner); + libcrux_sha3_simd_portable_load_last_a1_c6(&self->inner, borrowed, (size_t)0U, + self->buf_len); + libcrux_sha3_generic_keccak_keccakf1600_80_04(&self->inner); } /** -This function found in impl -{(libcrux_sha3::portable::incremental::XofAbsorb<168: usize> for -libcrux_sha3::portable::incremental::Shake128Absorb)} +This function found in impl {libcrux_sha3::portable::incremental::Xof<168usize> +for libcrux_sha3::portable::incremental::Shake128Xof} */ -static inline libcrux_sha3_generic_keccak_KeccakXofState_78 -libcrux_sha3_portable_incremental_absorb_final_1c( - libcrux_sha3_generic_keccak_KeccakXofState_78 self, Eurydice_slice input) { +static inline void libcrux_sha3_portable_incremental_absorb_final_26( + libcrux_sha3_generic_keccak_xof_KeccakXofState_97 *self, + Eurydice_slice input) { Eurydice_slice buf[1U] = {input}; - libcrux_sha3_generic_keccak_absorb_final_9d_250(&self, buf); - return self; + libcrux_sha3_generic_keccak_xof_absorb_final_35_9e0(self, buf); } /** - An all zero block -*/ -/** -This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} +This function found in impl +{libcrux_sha3::generic_keccak::xof::KeccakXofState[TraitClause@0, TraitClause@1]} */ /** -A monomorphic instance of libcrux_sha3.generic_keccak.zero_block_9d +A monomorphic instance of libcrux_sha3.generic_keccak.xof.zero_block_35 with types uint64_t with const generics - PARALLEL_LANES= 1 - RATE= 168 */ -static inline void libcrux_sha3_generic_keccak_zero_block_9d_e60( +static inline void libcrux_sha3_generic_keccak_xof_zero_block_35_c60( uint8_t ret[168U]) { - ret[0U] = 0U; - ret[1U] = 0U; - ret[2U] = 0U; - ret[3U] = 0U; - ret[4U] = 0U; - ret[5U] = 0U; - ret[6U] = 0U; - ret[7U] = 0U; - ret[8U] = 0U; - ret[9U] = 0U; - ret[10U] = 0U; - ret[11U] = 0U; - ret[12U] = 0U; - ret[13U] = 0U; - ret[14U] = 0U; - ret[15U] = 0U; - ret[16U] = 0U; - ret[17U] = 0U; - ret[18U] = 0U; - ret[19U] = 0U; - ret[20U] = 0U; - ret[21U] = 0U; - ret[22U] = 0U; - ret[23U] = 0U; - ret[24U] = 0U; - ret[25U] = 0U; - ret[26U] = 0U; - ret[27U] = 0U; - ret[28U] = 0U; - ret[29U] = 0U; - ret[30U] = 0U; - ret[31U] = 0U; - ret[32U] = 0U; - ret[33U] = 0U; - ret[34U] = 0U; - ret[35U] = 0U; - ret[36U] = 0U; - ret[37U] = 0U; - ret[38U] = 0U; - ret[39U] = 0U; - ret[40U] = 0U; - ret[41U] = 0U; - ret[42U] = 0U; - ret[43U] = 0U; - ret[44U] = 0U; - ret[45U] = 0U; - ret[46U] = 0U; - ret[47U] = 0U; - ret[48U] = 0U; - ret[49U] = 0U; - ret[50U] = 0U; - ret[51U] = 0U; - ret[52U] = 0U; - ret[53U] = 0U; - ret[54U] = 0U; - ret[55U] = 0U; - ret[56U] = 0U; - ret[57U] = 0U; - ret[58U] = 0U; - ret[59U] = 0U; - ret[60U] = 0U; - ret[61U] = 0U; - ret[62U] = 0U; - ret[63U] = 0U; - ret[64U] = 0U; - ret[65U] = 0U; - ret[66U] = 0U; - ret[67U] = 0U; - ret[68U] = 0U; - ret[69U] = 0U; - ret[70U] = 0U; - ret[71U] = 0U; - ret[72U] = 0U; - ret[73U] = 0U; - ret[74U] = 0U; - ret[75U] = 0U; - ret[76U] = 0U; - ret[77U] = 0U; - ret[78U] = 0U; - ret[79U] = 0U; - ret[80U] = 0U; - ret[81U] = 0U; - ret[82U] = 0U; - ret[83U] = 0U; - ret[84U] = 0U; - ret[85U] = 0U; - ret[86U] = 0U; - ret[87U] = 0U; - ret[88U] = 0U; - ret[89U] = 0U; - ret[90U] = 0U; - ret[91U] = 0U; - ret[92U] = 0U; - ret[93U] = 0U; - ret[94U] = 0U; - ret[95U] = 0U; - ret[96U] = 0U; - ret[97U] = 0U; - ret[98U] = 0U; - ret[99U] = 0U; - ret[100U] = 0U; - ret[101U] = 0U; - ret[102U] = 0U; - ret[103U] = 0U; - ret[104U] = 0U; - ret[105U] = 0U; - ret[106U] = 0U; - ret[107U] = 0U; - ret[108U] = 0U; - ret[109U] = 0U; - ret[110U] = 0U; - ret[111U] = 0U; - ret[112U] = 0U; - ret[113U] = 0U; - ret[114U] = 0U; - ret[115U] = 0U; - ret[116U] = 0U; - ret[117U] = 0U; - ret[118U] = 0U; - ret[119U] = 0U; - ret[120U] = 0U; - ret[121U] = 0U; - ret[122U] = 0U; - ret[123U] = 0U; - ret[124U] = 0U; - ret[125U] = 0U; - ret[126U] = 0U; - ret[127U] = 0U; - ret[128U] = 0U; - ret[129U] = 0U; - ret[130U] = 0U; - ret[131U] = 0U; - ret[132U] = 0U; - ret[133U] = 0U; - ret[134U] = 0U; - ret[135U] = 0U; - ret[136U] = 0U; - ret[137U] = 0U; - ret[138U] = 0U; - ret[139U] = 0U; - ret[140U] = 0U; - ret[141U] = 0U; - ret[142U] = 0U; - ret[143U] = 0U; - ret[144U] = 0U; - ret[145U] = 0U; - ret[146U] = 0U; - ret[147U] = 0U; - ret[148U] = 0U; - ret[149U] = 0U; - ret[150U] = 0U; - ret[151U] = 0U; - ret[152U] = 0U; - ret[153U] = 0U; - ret[154U] = 0U; - ret[155U] = 0U; - ret[156U] = 0U; - ret[157U] = 0U; - ret[158U] = 0U; - ret[159U] = 0U; - ret[160U] = 0U; - ret[161U] = 0U; - ret[162U] = 0U; - ret[163U] = 0U; - ret[164U] = 0U; - ret[165U] = 0U; - ret[166U] = 0U; - ret[167U] = 0U; -} - -/** - Generate a new keccak xof state. -*/ -/** -This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} -*/ -/** -A monomorphic instance of libcrux_sha3.generic_keccak.new_9d -with types uint64_t -with const generics -- PARALLEL_LANES= 1 -- RATE= 168 -*/ -static inline libcrux_sha3_generic_keccak_KeccakXofState_78 -libcrux_sha3_generic_keccak_new_9d_7e0(void) { - libcrux_sha3_generic_keccak_KeccakXofState_78 lit; - lit.inner = libcrux_sha3_generic_keccak_new_1e_f4(); - uint8_t ret[168U]; - libcrux_sha3_generic_keccak_zero_block_9d_e60(ret); - memcpy(lit.buf[0U], ret, (size_t)168U * sizeof(uint8_t)); - lit.buf_len = (size_t)0U; - lit.sponge = false; - return lit; + memset(ret, 0U, 168U * sizeof(uint8_t)); } /** This function found in impl -{(libcrux_sha3::portable::incremental::XofAbsorb<168: usize> for -libcrux_sha3::portable::incremental::Shake128Absorb)} -*/ -static inline libcrux_sha3_generic_keccak_KeccakXofState_78 -libcrux_sha3_portable_incremental_new_1c(void) { - return libcrux_sha3_generic_keccak_new_9d_7e0(); -} - -/** - `out` has the exact size we want here. It must be less than or equal to `RATE`. -*/ -/** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} -*/ -/** -A monomorphic instance of libcrux_sha3.portable_keccak.store_5a -with const generics -- RATE= 136 -*/ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_5a_1c( - uint64_t (*state)[5U], Eurydice_slice out[1U]) { - size_t num_full_blocks = Eurydice_slice_len(out[0U], uint8_t) / (size_t)8U; - size_t last_block_len = Eurydice_slice_len(out[0U], uint8_t) % (size_t)8U; - for (size_t i = (size_t)0U; i < num_full_blocks; i++) { - size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_slice_subslice2( - out[0U], i0 * (size_t)8U, i0 * (size_t)8U + (size_t)8U, uint8_t); - uint8_t ret[8U]; - core_num__u64_9__to_le_bytes(state[i0 / (size_t)5U][i0 % (size_t)5U], ret); - Eurydice_slice_copy( - uu____0, Eurydice_array_to_slice((size_t)8U, ret, uint8_t), uint8_t); - } - if (last_block_len != (size_t)0U) { - Eurydice_slice uu____1 = Eurydice_slice_subslice2( - out[0U], num_full_blocks * (size_t)8U, - num_full_blocks * (size_t)8U + last_block_len, uint8_t); - uint8_t ret[8U]; - core_num__u64_9__to_le_bytes( - state[num_full_blocks / (size_t)5U][num_full_blocks % (size_t)5U], ret); - Eurydice_slice_copy( - uu____1, - Eurydice_array_to_subslice2(ret, (size_t)0U, last_block_len, uint8_t), - uint8_t); - } -} - -/** - Squeeze `N` x `LEN` bytes. -*/ -/** -This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} +{libcrux_sha3::generic_keccak::xof::KeccakXofState[TraitClause@0, TraitClause@1]} */ /** -A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_9d +A monomorphic instance of libcrux_sha3.generic_keccak.xof.new_35 with types uint64_t with const generics - PARALLEL_LANES= 1 -- RATE= 136 +- RATE= 168 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_9d_96( - libcrux_sha3_generic_keccak_KeccakXofState_4f *self, - Eurydice_slice out[1U]) { - if (self->sponge) { - libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner); - } - size_t out_len = Eurydice_slice_len(out[0U], uint8_t); - size_t blocks = out_len / (size_t)136U; - size_t last = out_len - out_len % (size_t)136U; - size_t mid; - if ((size_t)136U >= out_len) { - mid = out_len; - } else { - mid = (size_t)136U; - } - Eurydice_slice_uint8_t_1size_t__x2 uu____0 = - libcrux_sha3_portable_keccak_split_at_mut_n_5a(out, mid); - Eurydice_slice out00[1U]; - memcpy(out00, uu____0.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice out_rest[1U]; - memcpy(out_rest, uu____0.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak_store_5a_1c(self->inner.st, out00); - core_ops_range_Range_b3 iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter( - (CLITERAL(core_ops_range_Range_b3){.start = (size_t)1U, - .end = blocks}), - core_ops_range_Range_b3, core_ops_range_Range_b3); - while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( - &iter, size_t, Option_b3) - .tag == None) { - break; - } else { - Eurydice_slice_uint8_t_1size_t__x2 uu____1 = - libcrux_sha3_portable_keccak_split_at_mut_n_5a(out_rest, - (size_t)136U); - Eurydice_slice out0[1U]; - memcpy(out0, uu____1.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice tmp[1U]; - memcpy(tmp, uu____1.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner); - libcrux_sha3_portable_keccak_store_5a_1c(self->inner.st, out0); - memcpy(out_rest, tmp, (size_t)1U * sizeof(Eurydice_slice)); - } - } - if (last < out_len) { - libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner); - libcrux_sha3_portable_keccak_store_5a_1c(self->inner.st, out_rest); +static inline libcrux_sha3_generic_keccak_xof_KeccakXofState_97 +libcrux_sha3_generic_keccak_xof_new_35_c60(void) { + libcrux_sha3_generic_keccak_xof_KeccakXofState_97 lit; + lit.inner = libcrux_sha3_generic_keccak_new_80_04(); + uint8_t repeat_expression[1U][168U]; + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + libcrux_sha3_generic_keccak_xof_zero_block_35_c60(repeat_expression[i]); } - self->sponge = true; -} - -/** - Shake256 squeeze -*/ -/** -This function found in impl -{(libcrux_sha3::portable::incremental::XofSqueeze<136: usize> for -libcrux_sha3::portable::incremental::Shake256Squeeze)#3} -*/ -static inline void libcrux_sha3_portable_incremental_squeeze_8a( - libcrux_sha3_generic_keccak_KeccakXofState_4f *self, Eurydice_slice out) { - Eurydice_slice buf[1U] = {out}; - libcrux_sha3_generic_keccak_squeeze_9d_96(self, buf); + memcpy(lit.buf, repeat_expression, (size_t)1U * sizeof(uint8_t[168U])); + lit.buf_len = (size_t)0U; + lit.sponge = false; + return lit; } /** - `out` has the exact size we want here. It must be less than or equal to `RATE`. +This function found in impl {libcrux_sha3::portable::incremental::Xof<168usize> +for libcrux_sha3::portable::incremental::Shake128Xof} */ -/** -This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: -usize> for u64)} -*/ -/** -A monomorphic instance of libcrux_sha3.portable_keccak.store_5a -with const generics -- RATE= 168 -*/ -static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_5a_1c0( - uint64_t (*state)[5U], Eurydice_slice out[1U]) { - size_t num_full_blocks = Eurydice_slice_len(out[0U], uint8_t) / (size_t)8U; - size_t last_block_len = Eurydice_slice_len(out[0U], uint8_t) % (size_t)8U; - for (size_t i = (size_t)0U; i < num_full_blocks; i++) { - size_t i0 = i; - Eurydice_slice uu____0 = Eurydice_slice_subslice2( - out[0U], i0 * (size_t)8U, i0 * (size_t)8U + (size_t)8U, uint8_t); - uint8_t ret[8U]; - core_num__u64_9__to_le_bytes(state[i0 / (size_t)5U][i0 % (size_t)5U], ret); - Eurydice_slice_copy( - uu____0, Eurydice_array_to_slice((size_t)8U, ret, uint8_t), uint8_t); - } - if (last_block_len != (size_t)0U) { - Eurydice_slice uu____1 = Eurydice_slice_subslice2( - out[0U], num_full_blocks * (size_t)8U, - num_full_blocks * (size_t)8U + last_block_len, uint8_t); - uint8_t ret[8U]; - core_num__u64_9__to_le_bytes( - state[num_full_blocks / (size_t)5U][num_full_blocks % (size_t)5U], ret); - Eurydice_slice_copy( - uu____1, - Eurydice_array_to_subslice2(ret, (size_t)0U, last_block_len, uint8_t), - uint8_t); - } +static inline libcrux_sha3_generic_keccak_xof_KeccakXofState_97 +libcrux_sha3_portable_incremental_new_26(void) { + return libcrux_sha3_generic_keccak_xof_new_35_c60(); } /** - Squeeze `N` x `LEN` bytes. + Squeeze `N` x `LEN` bytes. Only `N = 1` for now. */ /** -This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} +This function found in impl +{libcrux_sha3::generic_keccak::xof::KeccakXofState[TraitClause@0, TraitClause@1]} */ /** -A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_9d +A monomorphic instance of libcrux_sha3.generic_keccak.xof.squeeze_85 with types uint64_t with const generics -- PARALLEL_LANES= 1 - RATE= 168 */ -static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_9d_960( - libcrux_sha3_generic_keccak_KeccakXofState_78 *self, - Eurydice_slice out[1U]) { +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_xof_squeeze_85_13( + libcrux_sha3_generic_keccak_xof_KeccakXofState_97 *self, + Eurydice_slice out) { if (self->sponge) { - libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner); - } - size_t out_len = Eurydice_slice_len(out[0U], uint8_t); - size_t blocks = out_len / (size_t)168U; - size_t last = out_len - out_len % (size_t)168U; - size_t mid; - if ((size_t)168U >= out_len) { - mid = out_len; - } else { - mid = (size_t)168U; - } - Eurydice_slice_uint8_t_1size_t__x2 uu____0 = - libcrux_sha3_portable_keccak_split_at_mut_n_5a(out, mid); - Eurydice_slice out00[1U]; - memcpy(out00, uu____0.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice out_rest[1U]; - memcpy(out_rest, uu____0.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_portable_keccak_store_5a_1c0(self->inner.st, out00); - core_ops_range_Range_b3 iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter( - (CLITERAL(core_ops_range_Range_b3){.start = (size_t)1U, - .end = blocks}), - core_ops_range_Range_b3, core_ops_range_Range_b3); - while (true) { - if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( - &iter, size_t, Option_b3) - .tag == None) { - break; + libcrux_sha3_generic_keccak_keccakf1600_80_04(&self->inner); + } + size_t out_len = Eurydice_slice_len(out, uint8_t); + if (out_len > (size_t)0U) { + if (out_len <= (size_t)168U) { + libcrux_sha3_simd_portable_squeeze_13_3a(&self->inner, out, (size_t)0U, + out_len); } else { - Eurydice_slice_uint8_t_1size_t__x2 uu____1 = - libcrux_sha3_portable_keccak_split_at_mut_n_5a(out_rest, - (size_t)168U); - Eurydice_slice out0[1U]; - memcpy(out0, uu____1.fst, (size_t)1U * sizeof(Eurydice_slice)); - Eurydice_slice tmp[1U]; - memcpy(tmp, uu____1.snd, (size_t)1U * sizeof(Eurydice_slice)); - libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner); - libcrux_sha3_portable_keccak_store_5a_1c0(self->inner.st, out0); - memcpy(out_rest, tmp, (size_t)1U * sizeof(Eurydice_slice)); + size_t blocks = out_len / (size_t)168U; + for (size_t i = (size_t)0U; i < blocks; i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_keccakf1600_80_04(&self->inner); + libcrux_sha3_simd_portable_squeeze_13_3a( + &self->inner, out, i0 * (size_t)168U, (size_t)168U); + } + size_t remaining = out_len % (size_t)168U; + if (remaining > (size_t)0U) { + libcrux_sha3_generic_keccak_keccakf1600_80_04(&self->inner); + libcrux_sha3_simd_portable_squeeze_13_3a( + &self->inner, out, blocks * (size_t)168U, remaining); + } } + self->sponge = true; } - if (last < out_len) { - libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner); - libcrux_sha3_portable_keccak_store_5a_1c0(self->inner.st, out_rest); - } - self->sponge = true; } /** Shake128 squeeze */ /** -This function found in impl -{(libcrux_sha3::portable::incremental::XofSqueeze<168: usize> for -libcrux_sha3::portable::incremental::Shake128Squeeze)#1} +This function found in impl {libcrux_sha3::portable::incremental::Xof<168usize> +for libcrux_sha3::portable::incremental::Shake128Xof} */ -static inline void libcrux_sha3_portable_incremental_squeeze_10( - libcrux_sha3_generic_keccak_KeccakXofState_78 *self, Eurydice_slice out) { - Eurydice_slice buf[1U] = {out}; - libcrux_sha3_generic_keccak_squeeze_9d_960(self, buf); +static inline void libcrux_sha3_portable_incremental_squeeze_26( + libcrux_sha3_generic_keccak_xof_KeccakXofState_97 *self, + Eurydice_slice out) { + libcrux_sha3_generic_keccak_xof_squeeze_85_13(self, out); } /** -This function found in impl {(core::clone::Clone for -libcrux_sha3::portable::KeccakState)} +This function found in impl {core::clone::Clone for +libcrux_sha3::portable::KeccakState} */ -static inline libcrux_sha3_generic_keccak_KeccakState_48 -libcrux_sha3_portable_clone_3d( - libcrux_sha3_generic_keccak_KeccakState_48 *self) { +static inline libcrux_sha3_generic_keccak_KeccakState_17 +libcrux_sha3_portable_clone_fe( + libcrux_sha3_generic_keccak_KeccakState_17 *self) { return self[0U]; } /** -This function found in impl {(core::convert::From for -u32)#1} +This function found in impl {core::convert::From for +u32} */ -static inline uint32_t libcrux_sha3_from_eb(libcrux_sha3_Algorithm v) { - uint32_t uu____0; +static inline uint32_t libcrux_sha3_from_6c(libcrux_sha3_Algorithm v) { switch (v) { - case libcrux_sha3_Sha224: { - uu____0 = 1U; + case libcrux_sha3_Algorithm_Sha224: { break; } - case libcrux_sha3_Sha256: { - uu____0 = 2U; - break; + case libcrux_sha3_Algorithm_Sha256: { + return 2U; } - case libcrux_sha3_Sha384: { - uu____0 = 3U; - break; + case libcrux_sha3_Algorithm_Sha384: { + return 3U; } - case libcrux_sha3_Sha512: { - uu____0 = 4U; - break; + case libcrux_sha3_Algorithm_Sha512: { + return 4U; } default: { KRML_HOST_EPRINTF("KaRaMeL incomplete match at %s:%d\n", __FILE__, @@ -5718,31 +5406,26 @@ static inline uint32_t libcrux_sha3_from_eb(libcrux_sha3_Algorithm v) { KRML_HOST_EXIT(253U); } } - return uu____0; + return 1U; } /** -This function found in impl {(core::convert::From for -libcrux_sha3::Algorithm)} +This function found in impl {core::convert::From for +libcrux_sha3::Algorithm} */ -static inline libcrux_sha3_Algorithm libcrux_sha3_from_2d(uint32_t v) { - libcrux_sha3_Algorithm uu____0; +static inline libcrux_sha3_Algorithm libcrux_sha3_from_29(uint32_t v) { switch (v) { case 1U: { - uu____0 = libcrux_sha3_Sha224; break; } case 2U: { - uu____0 = libcrux_sha3_Sha256; - break; + return libcrux_sha3_Algorithm_Sha256; } case 3U: { - uu____0 = libcrux_sha3_Sha384; - break; + return libcrux_sha3_Algorithm_Sha384; } case 4U: { - uu____0 = libcrux_sha3_Sha512; - break; + return libcrux_sha3_Algorithm_Sha512; } default: { KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, @@ -5750,52 +5433,40 @@ static inline libcrux_sha3_Algorithm libcrux_sha3_from_2d(uint32_t v) { KRML_HOST_EXIT(255U); } } - return uu____0; + return libcrux_sha3_Algorithm_Sha224; } -typedef uint8_t libcrux_sha3_Sha3_512Digest[64U]; - -typedef uint8_t libcrux_sha3_Sha3_384Digest[48U]; - -typedef uint8_t libcrux_sha3_Sha3_256Digest[32U]; - -typedef uint8_t libcrux_sha3_Sha3_224Digest[28U]; - #if defined(__cplusplus) } #endif -#define __libcrux_sha3_portable_H_DEFINED -#endif +#define libcrux_sha3_portable_H_DEFINED +#endif /* libcrux_sha3_portable_H */ -/* from libcrux/libcrux-ml-kem/cg/libcrux_mlkem768_portable.h */ +/* from libcrux/libcrux-ml-kem/extracts/c_header_only/generated/libcrux_mlkem768_portable.h */ /* - * SPDX-FileCopyrightText: 2024 Cryspen Sarl + * SPDX-FileCopyrightText: 2025 Cryspen Sarl * * SPDX-License-Identifier: MIT or Apache-2.0 * * This code was generated with the following revisions: - * Charon: 6b5e110342a771a3e1c739b10294b1778e4be8b4 - * Eurydice: 31be7d65ca5d6acdacfb33652e478d24dd85c1cb - * Karamel: 3205d3365ea2790b02368f79fcee38e38d0b5908 - * F*: a32b316e521fa4f239b610ec8f1d15e78d62cbe8-dirty - * Libcrux: 4ad532b206174114dd4140b718e7794a28fc59ee + * Charon: 667d2fc98984ff7f3df989c2367e6c1fa4a000e7 + * Eurydice: 2381cbc416ef2ad0b561c362c500bc84f36b6785 + * Karamel: 80f5435f2fc505973c469a4afcc8d875cddd0d8b + * F*: 71d8221589d4d438af3706d89cb653cf53e18aab + * Libcrux: 68dfed5a4a9e40277f62828471c029afed1ecdcc */ -#ifndef __libcrux_mlkem768_portable_H -#define __libcrux_mlkem768_portable_H +#ifndef libcrux_mlkem768_portable_H +#define libcrux_mlkem768_portable_H + #if defined(__cplusplus) extern "C" { #endif -#define LIBCRUX_ML_KEM_HASH_FUNCTIONS_BLOCK_SIZE ((size_t)168U) - -#define LIBCRUX_ML_KEM_HASH_FUNCTIONS_THREE_BLOCKS \ - (LIBCRUX_ML_KEM_HASH_FUNCTIONS_BLOCK_SIZE * (size_t)3U) - -static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_G( +static inline void libcrux_ml_kem_hash_functions_portable_G( Eurydice_slice input, uint8_t ret[64U]) { uint8_t digest[64U] = {0U}; libcrux_sha3_portable_sha512( @@ -5803,7 +5474,7 @@ static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_G( memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); } -static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_H( +static inline void libcrux_ml_kem_hash_functions_portable_H( Eurydice_slice input, uint8_t ret[32U]) { uint8_t digest[32U] = {0U}; libcrux_sha3_portable_sha256( @@ -5811,15 +5482,6 @@ static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_H( memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); } -#define LIBCRUX_ML_KEM_IND_CCA_ENCAPS_SEED_SIZE \ - (LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) - -#define LIBCRUX_ML_KEM_IND_CCA_KEY_GENERATION_SEED_SIZE \ - (LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE + \ - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) - -typedef uint8_t libcrux_ml_kem_ind_cca_MlKemSharedSecret[32U]; - static const int16_t libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[128U] = {(int16_t)-1044, (int16_t)-758, (int16_t)-359, (int16_t)-1517, (int16_t)1493, (int16_t)1422, (int16_t)287, (int16_t)202, @@ -5854,17 +5516,19 @@ static const int16_t libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[128U] = (int16_t)-108, (int16_t)-308, (int16_t)996, (int16_t)991, (int16_t)958, (int16_t)-1460, (int16_t)1522, (int16_t)1628}; -#define LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR ((size_t)16U) +static KRML_MUSTINLINE int16_t libcrux_ml_kem_polynomial_zeta(size_t i) { + return libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[i]; +} -#define LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT \ - (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / \ - LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR) +#define LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT ((size_t)16U) -#define LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS ((int16_t)3329) +#define LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR ((size_t)16U) #define LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS \ ((int16_t)1353) +#define LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS ((int16_t)3329) + #define LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R \ (62209U) @@ -5877,155 +5541,23 @@ libcrux_ml_kem_vector_portable_vector_type_from_i16_array( Eurydice_slice array) { libcrux_ml_kem_vector_portable_vector_type_PortableVector lit; int16_t ret[16U]; - Result_c0 dst; + Result_0a dst; Eurydice_slice_to_array2( - &dst, Eurydice_slice_subslice2(array, (size_t)0U, (size_t)16U, int16_t), - Eurydice_slice, int16_t[16U]); - unwrap_41_f9(dst, ret); + &dst, Eurydice_slice_subslice3(array, (size_t)0U, (size_t)16U, int16_t *), + Eurydice_slice, int16_t[16U], TryFromSliceError); + unwrap_26_00(dst, ret); memcpy(lit.elements, ret, (size_t)16U * sizeof(int16_t)); return lit; } /** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_from_i16_array_0d(Eurydice_slice array) { - return libcrux_ml_kem_vector_portable_vector_type_from_i16_array(array); -} - -typedef struct uint8_t_x11_s { - uint8_t fst; - uint8_t snd; - uint8_t thd; - uint8_t f3; - uint8_t f4; - uint8_t f5; - uint8_t f6; - uint8_t f7; - uint8_t f8; - uint8_t f9; - uint8_t f10; -} uint8_t_x11; - -static KRML_MUSTINLINE uint8_t_x11 -libcrux_ml_kem_vector_portable_serialize_serialize_11_int(Eurydice_slice v) { - uint8_t r0 = (uint8_t)Eurydice_slice_index(v, (size_t)0U, int16_t, int16_t *); - uint8_t r1 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)1U, int16_t, - int16_t *) & - (int16_t)31) - << 3U | - (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)0U, int16_t, - int16_t *) >> - 8U); - uint8_t r2 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)2U, int16_t, - int16_t *) & - (int16_t)3) - << 6U | - (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)1U, int16_t, - int16_t *) >> - 5U); - uint8_t r3 = - (uint8_t)(Eurydice_slice_index(v, (size_t)2U, int16_t, int16_t *) >> 2U & - (int16_t)255); - uint8_t r4 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)3U, int16_t, - int16_t *) & - (int16_t)127) - << 1U | - (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)2U, int16_t, - int16_t *) >> - 10U); - uint8_t r5 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)4U, int16_t, - int16_t *) & - (int16_t)15) - << 4U | - (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)3U, int16_t, - int16_t *) >> - 7U); - uint8_t r6 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)5U, int16_t, - int16_t *) & - (int16_t)1) - << 7U | - (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)4U, int16_t, - int16_t *) >> - 4U); - uint8_t r7 = - (uint8_t)(Eurydice_slice_index(v, (size_t)5U, int16_t, int16_t *) >> 1U & - (int16_t)255); - uint8_t r8 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)6U, int16_t, - int16_t *) & - (int16_t)63) - << 2U | - (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)5U, int16_t, - int16_t *) >> - 9U); - uint8_t r9 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)7U, int16_t, - int16_t *) & - (int16_t)7) - << 5U | - (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)6U, int16_t, - int16_t *) >> - 6U); - uint8_t r10 = - (uint8_t)(Eurydice_slice_index(v, (size_t)7U, int16_t, int16_t *) >> 3U); - return (CLITERAL(uint8_t_x11){.fst = r0, - .snd = r1, - .thd = r2, - .f3 = r3, - .f4 = r4, - .f5 = r5, - .f6 = r6, - .f7 = r7, - .f8 = r8, - .f9 = r9, - .f10 = r10}); -} - -static KRML_MUSTINLINE void -libcrux_ml_kem_vector_portable_serialize_serialize_11( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v, - uint8_t ret[22U]) { - uint8_t_x11 r0_10 = libcrux_ml_kem_vector_portable_serialize_serialize_11_int( - Eurydice_array_to_subslice2(v.elements, (size_t)0U, (size_t)8U, int16_t)); - uint8_t_x11 r11_21 = - libcrux_ml_kem_vector_portable_serialize_serialize_11_int( - Eurydice_array_to_subslice2(v.elements, (size_t)8U, (size_t)16U, - int16_t)); - uint8_t result[22U] = {0U}; - result[0U] = r0_10.fst; - result[1U] = r0_10.snd; - result[2U] = r0_10.thd; - result[3U] = r0_10.f3; - result[4U] = r0_10.f4; - result[5U] = r0_10.f5; - result[6U] = r0_10.f6; - result[7U] = r0_10.f7; - result[8U] = r0_10.f8; - result[9U] = r0_10.f9; - result[10U] = r0_10.f10; - result[11U] = r11_21.fst; - result[12U] = r11_21.snd; - result[13U] = r11_21.thd; - result[14U] = r11_21.f3; - result[15U] = r11_21.f4; - result[16U] = r11_21.f5; - result[17U] = r11_21.f6; - result[18U] = r11_21.f7; - result[19U] = r11_21.f8; - result[20U] = r11_21.f9; - result[21U] = r11_21.f10; - memcpy(ret, result, (size_t)22U * sizeof(uint8_t)); -} - -/** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} -*/ -static inline void libcrux_ml_kem_vector_portable_serialize_11_0d( - libcrux_ml_kem_vector_portable_vector_type_PortableVector a, - uint8_t ret[22U]) { - libcrux_ml_kem_vector_portable_serialize_serialize_11(a, ret); +libcrux_ml_kem_vector_portable_from_i16_array_b8(Eurydice_slice array) { + return libcrux_ml_kem_vector_portable_vector_type_from_i16_array( + libcrux_secrets_int_classify_public_classify_ref_9b_39(array)); } typedef struct int16_t_x8_s { @@ -6039,666 +5571,22 @@ typedef struct int16_t_x8_s { int16_t f7; } int16_t_x8; -static KRML_MUSTINLINE int16_t_x8 -libcrux_ml_kem_vector_portable_serialize_deserialize_11_int( - Eurydice_slice bytes) { - int16_t r0 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *) & - (int16_t)7) - << 8U | - (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *); - int16_t r1 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *) & - (int16_t)63) - << 5U | - (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *) >> - 3U; - int16_t r2 = - (((int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *) & - (int16_t)1) - << 10U | - (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *) - << 2U) | - (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *) >> - 6U; - int16_t r3 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *) & - (int16_t)15) - << 7U | - (int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *) >> - 1U; - int16_t r4 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *) & - (int16_t)127) - << 4U | - (int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *) >> - 4U; - int16_t r5 = - (((int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *) & - (int16_t)3) - << 9U | - (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *) - << 1U) | - (int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *) >> - 7U; - int16_t r6 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *) & - (int16_t)31) - << 6U | - (int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *) >> - 2U; - int16_t r7 = - (int16_t)Eurydice_slice_index(bytes, (size_t)10U, uint8_t, uint8_t *) - << 3U | - (int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *) >> - 5U; - return (CLITERAL(int16_t_x8){.fst = r0, - .snd = r1, - .thd = r2, - .f3 = r3, - .f4 = r4, - .f5 = r5, - .f6 = r6, - .f7 = r7}); -} - static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector libcrux_ml_kem_vector_portable_vector_type_zero(void) { libcrux_ml_kem_vector_portable_vector_type_PortableVector lit; - lit.elements[0U] = (int16_t)0; - lit.elements[1U] = (int16_t)0; - lit.elements[2U] = (int16_t)0; - lit.elements[3U] = (int16_t)0; - lit.elements[4U] = (int16_t)0; - lit.elements[5U] = (int16_t)0; - lit.elements[6U] = (int16_t)0; - lit.elements[7U] = (int16_t)0; - lit.elements[8U] = (int16_t)0; - lit.elements[9U] = (int16_t)0; - lit.elements[10U] = (int16_t)0; - lit.elements[11U] = (int16_t)0; - lit.elements[12U] = (int16_t)0; - lit.elements[13U] = (int16_t)0; - lit.elements[14U] = (int16_t)0; - lit.elements[15U] = (int16_t)0; + int16_t ret[16U]; + int16_t buf[16U] = {0U}; + libcrux_secrets_int_public_integers_classify_27_46(buf, ret); + memcpy(lit.elements, ret, (size_t)16U * sizeof(int16_t)); return lit; } -static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_serialize_deserialize_11(Eurydice_slice bytes) { - int16_t_x8 v0_7 = libcrux_ml_kem_vector_portable_serialize_deserialize_11_int( - Eurydice_slice_subslice2(bytes, (size_t)0U, (size_t)11U, uint8_t)); - int16_t_x8 v8_15 = - libcrux_ml_kem_vector_portable_serialize_deserialize_11_int( - Eurydice_slice_subslice2(bytes, (size_t)11U, (size_t)22U, uint8_t)); - libcrux_ml_kem_vector_portable_vector_type_PortableVector v = - libcrux_ml_kem_vector_portable_vector_type_zero(); - v.elements[0U] = v0_7.fst; - v.elements[1U] = v0_7.snd; - v.elements[2U] = v0_7.thd; - v.elements[3U] = v0_7.f3; - v.elements[4U] = v0_7.f4; - v.elements[5U] = v0_7.f5; - v.elements[6U] = v0_7.f6; - v.elements[7U] = v0_7.f7; - v.elements[8U] = v8_15.fst; - v.elements[9U] = v8_15.snd; - v.elements[10U] = v8_15.thd; - v.elements[11U] = v8_15.f3; - v.elements[12U] = v8_15.f4; - v.elements[13U] = v8_15.f5; - v.elements[14U] = v8_15.f6; - v.elements[15U] = v8_15.f7; - return v; -} - -/** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} -*/ -static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_deserialize_11_0d(Eurydice_slice a) { - return libcrux_ml_kem_vector_portable_serialize_deserialize_11(a); -} - -static KRML_MUSTINLINE void -libcrux_ml_kem_vector_portable_vector_type_to_i16_array( - libcrux_ml_kem_vector_portable_vector_type_PortableVector x, - int16_t ret[16U]) { - memcpy(ret, x.elements, (size_t)16U * sizeof(int16_t)); -} - -/** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} -*/ -static inline void libcrux_ml_kem_vector_portable_to_i16_array_0d( - libcrux_ml_kem_vector_portable_vector_type_PortableVector x, - int16_t ret[16U]) { - libcrux_ml_kem_vector_portable_vector_type_to_i16_array(x, ret); -} - -static const uint8_t - libcrux_ml_kem_vector_rej_sample_table_REJECTION_SAMPLE_SHUFFLE_TABLE - [256U][16U] = {{255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, - 255U, 255U, 255U}, - {12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, - 255U, 255U, 255U}, - {10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, - 255U, 255U, 255U, 255U}, - {8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, - 13U, 255U, 255U}, - {14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, - 255U, 255U, 255U}, - {10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, - 15U, 255U, 255U}, - {12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, - 15U, 255U, 255U}, - {10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, - 15U, 255U, 255U}, - {8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, - 15U, 255U, 255U}, - {6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, - 255U, 255U, 255U, 255U, 255U}, - {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, - 15U, 255U, 255U}, - {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, - 255U, 255U, 255U, 255U}, - {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, - 15U, 255U, 255U}, - {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, - 15U, 255U, 255U}, - {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, - 13U, 14U, 15U}}; - -/** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +/** +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_ZERO_0d(void) { +libcrux_ml_kem_vector_portable_ZERO_b8(void) { return libcrux_ml_kem_vector_portable_vector_type_zero(); } @@ -6716,11 +5604,11 @@ libcrux_ml_kem_vector_portable_arithmetic_add( } /** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_add_0d( +libcrux_ml_kem_vector_portable_add_b8( libcrux_ml_kem_vector_portable_vector_type_PortableVector lhs, libcrux_ml_kem_vector_portable_vector_type_PortableVector *rhs) { return libcrux_ml_kem_vector_portable_arithmetic_add(lhs, rhs); @@ -6740,11 +5628,11 @@ libcrux_ml_kem_vector_portable_arithmetic_sub( } /** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_sub_0d( +libcrux_ml_kem_vector_portable_sub_b8( libcrux_ml_kem_vector_portable_vector_type_PortableVector lhs, libcrux_ml_kem_vector_portable_vector_type_PortableVector *rhs) { return libcrux_ml_kem_vector_portable_arithmetic_sub(lhs, rhs); @@ -6752,80 +5640,51 @@ libcrux_ml_kem_vector_portable_sub_0d( static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector libcrux_ml_kem_vector_portable_arithmetic_multiply_by_constant( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t c) { + libcrux_ml_kem_vector_portable_vector_type_PortableVector vec, int16_t c) { for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { size_t i0 = i; size_t uu____0 = i0; - v.elements[uu____0] = v.elements[uu____0] * c; + vec.elements[uu____0] = vec.elements[uu____0] * c; } - return v; + return vec; } /** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_multiply_by_constant_0d( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t c) { - return libcrux_ml_kem_vector_portable_arithmetic_multiply_by_constant(v, c); -} - -static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_arithmetic_bitwise_and_with_constant( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t c) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { - size_t i0 = i; - size_t uu____0 = i0; - v.elements[uu____0] = v.elements[uu____0] & c; - } - return v; +libcrux_ml_kem_vector_portable_multiply_by_constant_b8( + libcrux_ml_kem_vector_portable_vector_type_PortableVector vec, int16_t c) { + return libcrux_ml_kem_vector_portable_arithmetic_multiply_by_constant(vec, c); } /** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} + Note: This function is not secret independent + Only use with public values. */ -static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_bitwise_and_with_constant_0d( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t c) { - return libcrux_ml_kem_vector_portable_arithmetic_bitwise_and_with_constant(v, - c); -} - static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector libcrux_ml_kem_vector_portable_arithmetic_cond_subtract_3329( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { - core_ops_range_Range_b3 iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter( - (CLITERAL(core_ops_range_Range_b3){ - .start = (size_t)0U, - .end = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR}), - core_ops_range_Range_b3, core_ops_range_Range_b3); - while (true) { - Option_b3 uu____0 = - core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( - &iter, size_t, Option_b3); - if (!(uu____0.tag == None)) { - size_t i = uu____0.f0; - if (v.elements[i] >= (int16_t)3329) { - size_t uu____1 = i; - v.elements[uu____1] = v.elements[uu____1] - (int16_t)3329; - } - continue; + libcrux_ml_kem_vector_portable_vector_type_PortableVector vec) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + if (libcrux_secrets_int_public_integers_declassify_d8_39( + vec.elements[i0]) >= (int16_t)3329) { + size_t uu____0 = i0; + vec.elements[uu____0] = vec.elements[uu____0] - (int16_t)3329; } - return v; } + return vec; } /** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_cond_subtract_3329_0d( +libcrux_ml_kem_vector_portable_cond_subtract_3329_b8( libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { return libcrux_ml_kem_vector_portable_arithmetic_cond_subtract_3329(v); } @@ -6833,11 +5692,10 @@ libcrux_ml_kem_vector_portable_cond_subtract_3329_0d( #define LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_BARRETT_MULTIPLIER \ ((int32_t)20159) -#define LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_BARRETT_SHIFT ((int32_t)26) +#define LIBCRUX_ML_KEM_VECTOR_TRAITS_BARRETT_SHIFT ((int32_t)26) -#define LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_BARRETT_R \ - ((int32_t)1 << (uint32_t) \ - LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_BARRETT_SHIFT) +#define LIBCRUX_ML_KEM_VECTOR_TRAITS_BARRETT_R \ + ((int32_t)1 << (uint32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_BARRETT_SHIFT) /** Signed Barrett Reduction @@ -6850,50 +5708,47 @@ libcrux_ml_kem_vector_portable_cond_subtract_3329_0d( `|result| ≤ FIELD_MODULUS / 2 · (|value|/BARRETT_R + 1) - In particular, if `|value| < BARRETT_R`, then `|result| < FIELD_MODULUS`. + Note: The input bound is 28296 to prevent overflow in the multiplication of + quotient by FIELD_MODULUS + */ static inline int16_t libcrux_ml_kem_vector_portable_arithmetic_barrett_reduce_element( int16_t value) { - int32_t t = (int32_t)value * + int32_t t = libcrux_secrets_int_as_i32_f5(value) * LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_BARRETT_MULTIPLIER + - (LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_BARRETT_R >> 1U); - int16_t quotient = - (int16_t)(t >> - (uint32_t) - LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_BARRETT_SHIFT); + (LIBCRUX_ML_KEM_VECTOR_TRAITS_BARRETT_R >> 1U); + int16_t quotient = libcrux_secrets_int_as_i16_36( + t >> (uint32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_BARRETT_SHIFT); return value - quotient * LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; } static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector libcrux_ml_kem_vector_portable_arithmetic_barrett_reduce( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + libcrux_ml_kem_vector_portable_vector_type_PortableVector vec) { for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { size_t i0 = i; - v.elements[i0] = + int16_t vi = libcrux_ml_kem_vector_portable_arithmetic_barrett_reduce_element( - v.elements[i0]); + vec.elements[i0]); + vec.elements[i0] = vi; } - return v; + return vec; } /** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_barrett_reduce_0d( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { - return libcrux_ml_kem_vector_portable_arithmetic_barrett_reduce(v); +libcrux_ml_kem_vector_portable_barrett_reduce_b8( + libcrux_ml_kem_vector_portable_vector_type_PortableVector vector) { + return libcrux_ml_kem_vector_portable_arithmetic_barrett_reduce(vector); } #define LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_MONTGOMERY_SHIFT (16U) -#define LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_MONTGOMERY_R \ - ((int32_t)1 << (uint32_t) \ - LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_MONTGOMERY_SHIFT) - /** Signed Montgomery Reduction @@ -6903,27 +5758,32 @@ libcrux_ml_kem_vector_portable_barrett_reduce_0d( - o ≡ value · MONTGOMERY_R^(-1) (mod FIELD_MODULUS) - the absolute value of `o` is bound as follows: - `|result| ≤ (|value| / MONTGOMERY_R) + (FIELD_MODULUS / 2) + `|result| ≤ ceil(|value| / MONTGOMERY_R) + 1665 + + In particular, if `|value| ≤ FIELD_MODULUS-1 * FIELD_MODULUS-1`, then `|o| <= + FIELD_MODULUS-1`. And, if `|value| ≤ pow2 16 * FIELD_MODULUS-1`, then `|o| <= + FIELD_MODULUS + 1664 - In particular, if `|value| ≤ FIELD_MODULUS * MONTGOMERY_R`, then `|o| < (3 · - FIELD_MODULUS) / 2`. */ static inline int16_t libcrux_ml_kem_vector_portable_arithmetic_montgomery_reduce_element( int32_t value) { int32_t k = - (int32_t)(int16_t)value * - (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R; + libcrux_secrets_int_as_i32_f5(libcrux_secrets_int_as_i16_36(value)) * + libcrux_secrets_int_as_i32_b8( + libcrux_secrets_int_public_integers_classify_27_df( + LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R)); int32_t k_times_modulus = - (int32_t)(int16_t)k * (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; - int16_t c = - (int16_t)(k_times_modulus >> - (uint32_t) - LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_MONTGOMERY_SHIFT); - int16_t value_high = - (int16_t)(value >> - (uint32_t) - LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_MONTGOMERY_SHIFT); + libcrux_secrets_int_as_i32_f5(libcrux_secrets_int_as_i16_36(k)) * + libcrux_secrets_int_as_i32_f5( + libcrux_secrets_int_public_integers_classify_27_39( + LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); + int16_t c = libcrux_secrets_int_as_i16_36( + k_times_modulus >> + (uint32_t)LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_MONTGOMERY_SHIFT); + int16_t value_high = libcrux_secrets_int_as_i16_36( + value >> + (uint32_t)LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_MONTGOMERY_SHIFT); return value_high - c; } @@ -6941,32 +5801,85 @@ libcrux_ml_kem_vector_portable_arithmetic_montgomery_reduce_element( static KRML_MUSTINLINE int16_t libcrux_ml_kem_vector_portable_arithmetic_montgomery_multiply_fe_by_fer( int16_t fe, int16_t fer) { + int32_t product = + libcrux_secrets_int_as_i32_f5(fe) * libcrux_secrets_int_as_i32_f5(fer); return libcrux_ml_kem_vector_portable_arithmetic_montgomery_reduce_element( - (int32_t)fe * (int32_t)fer); + product); } static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector libcrux_ml_kem_vector_portable_arithmetic_montgomery_multiply_by_constant( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t c) { + libcrux_ml_kem_vector_portable_vector_type_PortableVector vec, int16_t c) { for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { size_t i0 = i; - v.elements[i0] = + vec.elements[i0] = libcrux_ml_kem_vector_portable_arithmetic_montgomery_multiply_fe_by_fer( - v.elements[i0], c); + vec.elements[i0], c); } - return v; + return vec; } /** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_0d( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t r) { +libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_b8( + libcrux_ml_kem_vector_portable_vector_type_PortableVector vector, + int16_t constant) { return libcrux_ml_kem_vector_portable_arithmetic_montgomery_multiply_by_constant( - v, r); + vector, libcrux_secrets_int_public_integers_classify_27_39(constant)); +} + +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_arithmetic_bitwise_and_with_constant( + libcrux_ml_kem_vector_portable_vector_type_PortableVector vec, int16_t c) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + size_t uu____0 = i0; + vec.elements[uu____0] = vec.elements[uu____0] & c; + } + return vec; +} + +/** +A monomorphic instance of libcrux_ml_kem.vector.portable.arithmetic.shift_right +with const generics +- SHIFT_BY= 15 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_arithmetic_shift_right_ef( + libcrux_ml_kem_vector_portable_vector_type_PortableVector vec) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + vec.elements[i0] = vec.elements[i0] >> (uint32_t)(int32_t)15; + } + return vec; +} + +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_arithmetic_to_unsigned_representative( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a) { + libcrux_ml_kem_vector_portable_vector_type_PortableVector t = + libcrux_ml_kem_vector_portable_arithmetic_shift_right_ef(a); + libcrux_ml_kem_vector_portable_vector_type_PortableVector fm = + libcrux_ml_kem_vector_portable_arithmetic_bitwise_and_with_constant( + t, LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + return libcrux_ml_kem_vector_portable_arithmetic_add(a, &fm); +} + +/** +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_to_unsigned_representative_b8( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a) { + return libcrux_ml_kem_vector_portable_arithmetic_to_unsigned_representative( + a); } /** @@ -6994,34 +5907,38 @@ libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_0d( static inline uint8_t libcrux_ml_kem_vector_portable_compress_compress_message_coefficient( uint16_t fe) { - int16_t shifted = (int16_t)1664 - (int16_t)fe; + int16_t shifted = + libcrux_secrets_int_public_integers_classify_27_39((int16_t)1664) - + libcrux_secrets_int_as_i16_ca(fe); int16_t mask = shifted >> 15U; int16_t shifted_to_positive = mask ^ shifted; int16_t shifted_positive_in_range = shifted_to_positive - (int16_t)832; - return (uint8_t)(shifted_positive_in_range >> 15U & (int16_t)1); + int16_t r0 = shifted_positive_in_range >> 15U; + int16_t r1 = r0 & (int16_t)1; + return libcrux_secrets_int_as_u8_f5(r1); } static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector libcrux_ml_kem_vector_portable_compress_compress_1( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + libcrux_ml_kem_vector_portable_vector_type_PortableVector a) { for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { size_t i0 = i; - v.elements[i0] = (int16_t) + a.elements[i0] = libcrux_secrets_int_as_i16_59( libcrux_ml_kem_vector_portable_compress_compress_message_coefficient( - (uint16_t)v.elements[i0]); + libcrux_secrets_int_as_u16_f5(a.elements[i0]))); } - return v; + return a; } /** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_compress_1_0d( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { - return libcrux_ml_kem_vector_portable_compress_compress_1(v); +libcrux_ml_kem_vector_portable_compress_1_b8( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a) { + return libcrux_ml_kem_vector_portable_compress_compress_1(a); } static KRML_MUSTINLINE uint32_t @@ -7033,54 +5950,81 @@ libcrux_ml_kem_vector_portable_arithmetic_get_n_least_significant_bits( static inline int16_t libcrux_ml_kem_vector_portable_compress_compress_ciphertext_coefficient( uint8_t coefficient_bits, uint16_t fe) { - uint64_t compressed = (uint64_t)fe << (uint32_t)coefficient_bits; + uint64_t compressed = libcrux_secrets_int_as_u64_ca(fe) + << (uint32_t)coefficient_bits; compressed = compressed + 1664ULL; compressed = compressed * 10321340ULL; compressed = compressed >> 35U; - return (int16_t) + return libcrux_secrets_int_as_i16_b8( libcrux_ml_kem_vector_portable_arithmetic_get_n_least_significant_bits( - coefficient_bits, (uint32_t)compressed); + coefficient_bits, libcrux_secrets_int_as_u32_a3(compressed))); +} + +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_compress_decompress_1( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a) { + libcrux_ml_kem_vector_portable_vector_type_PortableVector z = + libcrux_ml_kem_vector_portable_vector_type_zero(); + libcrux_ml_kem_vector_portable_vector_type_PortableVector s = + libcrux_ml_kem_vector_portable_arithmetic_sub(z, &a); + libcrux_ml_kem_vector_portable_vector_type_PortableVector res = + libcrux_ml_kem_vector_portable_arithmetic_bitwise_and_with_constant( + s, (int16_t)1665); + return res; +} + +/** +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_decompress_1_b8( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a) { + return libcrux_ml_kem_vector_portable_compress_decompress_1(a); } static KRML_MUSTINLINE void libcrux_ml_kem_vector_portable_ntt_ntt_step( - libcrux_ml_kem_vector_portable_vector_type_PortableVector *v, int16_t zeta, - size_t i, size_t j) { + libcrux_ml_kem_vector_portable_vector_type_PortableVector *vec, + int16_t zeta, size_t i, size_t j) { int16_t t = libcrux_ml_kem_vector_portable_arithmetic_montgomery_multiply_fe_by_fer( - v->elements[j], zeta); - v->elements[j] = v->elements[i] - t; - v->elements[i] = v->elements[i] + t; + vec->elements[j], + libcrux_secrets_int_public_integers_classify_27_39(zeta)); + int16_t a_minus_t = vec->elements[i] - t; + int16_t a_plus_t = vec->elements[i] + t; + vec->elements[j] = a_minus_t; + vec->elements[i] = a_plus_t; } static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector libcrux_ml_kem_vector_portable_ntt_ntt_layer_1_step( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t zeta0, - int16_t zeta1, int16_t zeta2, int16_t zeta3) { - libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta0, (size_t)0U, + libcrux_ml_kem_vector_portable_vector_type_PortableVector vec, + int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3) { + libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta0, (size_t)0U, (size_t)2U); - libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta0, (size_t)1U, + libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta0, (size_t)1U, (size_t)3U); - libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta1, (size_t)4U, + libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta1, (size_t)4U, (size_t)6U); - libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta1, (size_t)5U, + libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta1, (size_t)5U, (size_t)7U); - libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta2, (size_t)8U, + libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta2, (size_t)8U, (size_t)10U); - libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta2, (size_t)9U, + libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta2, (size_t)9U, (size_t)11U); - libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta3, (size_t)12U, + libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta3, (size_t)12U, (size_t)14U); - libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta3, (size_t)13U, + libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta3, (size_t)13U, (size_t)15U); - return v; + return vec; } /** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_ntt_layer_1_step_0d( +libcrux_ml_kem_vector_portable_ntt_layer_1_step_b8( libcrux_ml_kem_vector_portable_vector_type_PortableVector a, int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3) { return libcrux_ml_kem_vector_portable_ntt_ntt_layer_1_step(a, zeta0, zeta1, @@ -7089,33 +6033,33 @@ libcrux_ml_kem_vector_portable_ntt_layer_1_step_0d( static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector libcrux_ml_kem_vector_portable_ntt_ntt_layer_2_step( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t zeta0, - int16_t zeta1) { - libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta0, (size_t)0U, + libcrux_ml_kem_vector_portable_vector_type_PortableVector vec, + int16_t zeta0, int16_t zeta1) { + libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta0, (size_t)0U, (size_t)4U); - libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta0, (size_t)1U, + libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta0, (size_t)1U, (size_t)5U); - libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta0, (size_t)2U, + libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta0, (size_t)2U, (size_t)6U); - libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta0, (size_t)3U, + libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta0, (size_t)3U, (size_t)7U); - libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta1, (size_t)8U, + libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta1, (size_t)8U, (size_t)12U); - libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta1, (size_t)9U, + libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta1, (size_t)9U, (size_t)13U); - libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta1, (size_t)10U, + libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta1, (size_t)10U, (size_t)14U); - libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta1, (size_t)11U, + libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta1, (size_t)11U, (size_t)15U); - return v; + return vec; } /** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_ntt_layer_2_step_0d( +libcrux_ml_kem_vector_portable_ntt_layer_2_step_b8( libcrux_ml_kem_vector_portable_vector_type_PortableVector a, int16_t zeta0, int16_t zeta1) { return libcrux_ml_kem_vector_portable_ntt_ntt_layer_2_step(a, zeta0, zeta1); @@ -7123,75 +6067,80 @@ libcrux_ml_kem_vector_portable_ntt_layer_2_step_0d( static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector libcrux_ml_kem_vector_portable_ntt_ntt_layer_3_step( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t zeta) { - libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta, (size_t)0U, (size_t)8U); - libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta, (size_t)1U, (size_t)9U); - libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta, (size_t)2U, + libcrux_ml_kem_vector_portable_vector_type_PortableVector vec, + int16_t zeta) { + libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta, (size_t)0U, + (size_t)8U); + libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta, (size_t)1U, + (size_t)9U); + libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta, (size_t)2U, (size_t)10U); - libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta, (size_t)3U, + libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta, (size_t)3U, (size_t)11U); - libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta, (size_t)4U, + libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta, (size_t)4U, (size_t)12U); - libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta, (size_t)5U, + libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta, (size_t)5U, (size_t)13U); - libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta, (size_t)6U, + libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta, (size_t)6U, (size_t)14U); - libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta, (size_t)7U, + libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta, (size_t)7U, (size_t)15U); - return v; + return vec; } /** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_ntt_layer_3_step_0d( +libcrux_ml_kem_vector_portable_ntt_layer_3_step_b8( libcrux_ml_kem_vector_portable_vector_type_PortableVector a, int16_t zeta) { return libcrux_ml_kem_vector_portable_ntt_ntt_layer_3_step(a, zeta); } static KRML_MUSTINLINE void libcrux_ml_kem_vector_portable_ntt_inv_ntt_step( - libcrux_ml_kem_vector_portable_vector_type_PortableVector *v, int16_t zeta, - size_t i, size_t j) { - int16_t a_minus_b = v->elements[j] - v->elements[i]; - v->elements[i] = - libcrux_ml_kem_vector_portable_arithmetic_barrett_reduce_element( - v->elements[i] + v->elements[j]); - v->elements[j] = + libcrux_ml_kem_vector_portable_vector_type_PortableVector *vec, + int16_t zeta, size_t i, size_t j) { + int16_t a_minus_b = vec->elements[j] - vec->elements[i]; + int16_t a_plus_b = vec->elements[j] + vec->elements[i]; + int16_t o0 = libcrux_ml_kem_vector_portable_arithmetic_barrett_reduce_element( + a_plus_b); + int16_t o1 = libcrux_ml_kem_vector_portable_arithmetic_montgomery_multiply_fe_by_fer( - a_minus_b, zeta); + a_minus_b, libcrux_secrets_int_public_integers_classify_27_39(zeta)); + vec->elements[i] = o0; + vec->elements[j] = o1; } static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector libcrux_ml_kem_vector_portable_ntt_inv_ntt_layer_1_step( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t zeta0, - int16_t zeta1, int16_t zeta2, int16_t zeta3) { - libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta0, (size_t)0U, + libcrux_ml_kem_vector_portable_vector_type_PortableVector vec, + int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3) { + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta0, (size_t)0U, (size_t)2U); - libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta0, (size_t)1U, + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta0, (size_t)1U, (size_t)3U); - libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta1, (size_t)4U, + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta1, (size_t)4U, (size_t)6U); - libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta1, (size_t)5U, + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta1, (size_t)5U, (size_t)7U); - libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta2, (size_t)8U, + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta2, (size_t)8U, (size_t)10U); - libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta2, (size_t)9U, + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta2, (size_t)9U, (size_t)11U); - libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta3, (size_t)12U, + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta3, (size_t)12U, (size_t)14U); - libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta3, (size_t)13U, + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta3, (size_t)13U, (size_t)15U); - return v; + return vec; } /** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_inv_ntt_layer_1_step_0d( +libcrux_ml_kem_vector_portable_inv_ntt_layer_1_step_b8( libcrux_ml_kem_vector_portable_vector_type_PortableVector a, int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3) { return libcrux_ml_kem_vector_portable_ntt_inv_ntt_layer_1_step( @@ -7200,33 +6149,33 @@ libcrux_ml_kem_vector_portable_inv_ntt_layer_1_step_0d( static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector libcrux_ml_kem_vector_portable_ntt_inv_ntt_layer_2_step( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t zeta0, - int16_t zeta1) { - libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta0, (size_t)0U, + libcrux_ml_kem_vector_portable_vector_type_PortableVector vec, + int16_t zeta0, int16_t zeta1) { + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta0, (size_t)0U, (size_t)4U); - libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta0, (size_t)1U, + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta0, (size_t)1U, (size_t)5U); - libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta0, (size_t)2U, + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta0, (size_t)2U, (size_t)6U); - libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta0, (size_t)3U, + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta0, (size_t)3U, (size_t)7U); - libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta1, (size_t)8U, + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta1, (size_t)8U, (size_t)12U); - libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta1, (size_t)9U, + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta1, (size_t)9U, (size_t)13U); - libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta1, (size_t)10U, + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta1, (size_t)10U, (size_t)14U); - libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta1, (size_t)11U, + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta1, (size_t)11U, (size_t)15U); - return v; + return vec; } /** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_inv_ntt_layer_2_step_0d( +libcrux_ml_kem_vector_portable_inv_ntt_layer_2_step_b8( libcrux_ml_kem_vector_portable_vector_type_PortableVector a, int16_t zeta0, int16_t zeta1) { return libcrux_ml_kem_vector_portable_ntt_inv_ntt_layer_2_step(a, zeta0, @@ -7235,32 +6184,33 @@ libcrux_ml_kem_vector_portable_inv_ntt_layer_2_step_0d( static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector libcrux_ml_kem_vector_portable_ntt_inv_ntt_layer_3_step( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t zeta) { - libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta, (size_t)0U, + libcrux_ml_kem_vector_portable_vector_type_PortableVector vec, + int16_t zeta) { + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta, (size_t)0U, (size_t)8U); - libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta, (size_t)1U, + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta, (size_t)1U, (size_t)9U); - libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta, (size_t)2U, + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta, (size_t)2U, (size_t)10U); - libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta, (size_t)3U, + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta, (size_t)3U, (size_t)11U); - libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta, (size_t)4U, + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta, (size_t)4U, (size_t)12U); - libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta, (size_t)5U, + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta, (size_t)5U, (size_t)13U); - libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta, (size_t)6U, + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta, (size_t)6U, (size_t)14U); - libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta, (size_t)7U, + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta, (size_t)7U, (size_t)15U); - return v; + return vec; } /** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_inv_ntt_layer_3_step_0d( +libcrux_ml_kem_vector_portable_inv_ntt_layer_3_step_b8( libcrux_ml_kem_vector_portable_vector_type_PortableVector a, int16_t zeta) { return libcrux_ml_kem_vector_portable_ntt_inv_ntt_layer_3_step(a, zeta); } @@ -7291,20 +6241,34 @@ static KRML_MUSTINLINE void libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials( libcrux_ml_kem_vector_portable_vector_type_PortableVector *a, libcrux_ml_kem_vector_portable_vector_type_PortableVector *b, int16_t zeta, - size_t i, size_t j, - libcrux_ml_kem_vector_portable_vector_type_PortableVector *out) { - int16_t o0 = libcrux_ml_kem_vector_portable_arithmetic_montgomery_reduce_element( - (int32_t)a->elements[i] * (int32_t)b->elements[i] + - (int32_t) - libcrux_ml_kem_vector_portable_arithmetic_montgomery_reduce_element( - (int32_t)a->elements[j] * (int32_t)b->elements[j]) * - (int32_t)zeta); + size_t i, libcrux_ml_kem_vector_portable_vector_type_PortableVector *out) { + int16_t ai = a->elements[(size_t)2U * i]; + int16_t bi = b->elements[(size_t)2U * i]; + int16_t aj = a->elements[(size_t)2U * i + (size_t)1U]; + int16_t bj = b->elements[(size_t)2U * i + (size_t)1U]; + int32_t ai_bi = + libcrux_secrets_int_as_i32_f5(ai) * libcrux_secrets_int_as_i32_f5(bi); + int32_t aj_bj_ = + libcrux_secrets_int_as_i32_f5(aj) * libcrux_secrets_int_as_i32_f5(bj); + int16_t aj_bj = + libcrux_ml_kem_vector_portable_arithmetic_montgomery_reduce_element( + aj_bj_); + int32_t aj_bj_zeta = libcrux_secrets_int_as_i32_f5(aj_bj) * + libcrux_secrets_int_as_i32_f5(zeta); + int32_t ai_bi_aj_bj = ai_bi + aj_bj_zeta; + int16_t o0 = + libcrux_ml_kem_vector_portable_arithmetic_montgomery_reduce_element( + ai_bi_aj_bj); + int32_t ai_bj = + libcrux_secrets_int_as_i32_f5(ai) * libcrux_secrets_int_as_i32_f5(bj); + int32_t aj_bi = + libcrux_secrets_int_as_i32_f5(aj) * libcrux_secrets_int_as_i32_f5(bi); + int32_t ai_bj_aj_bi = ai_bj + aj_bi; int16_t o1 = libcrux_ml_kem_vector_portable_arithmetic_montgomery_reduce_element( - (int32_t)a->elements[i] * (int32_t)b->elements[j] + - (int32_t)a->elements[j] * (int32_t)b->elements[i]); - out->elements[i] = o0; - out->elements[j] = o1; + ai_bj_aj_bi); + out->elements[(size_t)2U * i] = o0; + out->elements[(size_t)2U * i + (size_t)1U] = o1; } static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector @@ -7312,33 +6276,45 @@ libcrux_ml_kem_vector_portable_ntt_ntt_multiply( libcrux_ml_kem_vector_portable_vector_type_PortableVector *lhs, libcrux_ml_kem_vector_portable_vector_type_PortableVector *rhs, int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3) { + int16_t nzeta0 = -zeta0; + int16_t nzeta1 = -zeta1; + int16_t nzeta2 = -zeta2; + int16_t nzeta3 = -zeta3; libcrux_ml_kem_vector_portable_vector_type_PortableVector out = libcrux_ml_kem_vector_portable_vector_type_zero(); libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials( - lhs, rhs, zeta0, (size_t)0U, (size_t)1U, &out); + lhs, rhs, libcrux_secrets_int_public_integers_classify_27_39(zeta0), + (size_t)0U, &out); libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials( - lhs, rhs, -zeta0, (size_t)2U, (size_t)3U, &out); + lhs, rhs, libcrux_secrets_int_public_integers_classify_27_39(nzeta0), + (size_t)1U, &out); libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials( - lhs, rhs, zeta1, (size_t)4U, (size_t)5U, &out); + lhs, rhs, libcrux_secrets_int_public_integers_classify_27_39(zeta1), + (size_t)2U, &out); libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials( - lhs, rhs, -zeta1, (size_t)6U, (size_t)7U, &out); + lhs, rhs, libcrux_secrets_int_public_integers_classify_27_39(nzeta1), + (size_t)3U, &out); libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials( - lhs, rhs, zeta2, (size_t)8U, (size_t)9U, &out); + lhs, rhs, libcrux_secrets_int_public_integers_classify_27_39(zeta2), + (size_t)4U, &out); libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials( - lhs, rhs, -zeta2, (size_t)10U, (size_t)11U, &out); + lhs, rhs, libcrux_secrets_int_public_integers_classify_27_39(nzeta2), + (size_t)5U, &out); libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials( - lhs, rhs, zeta3, (size_t)12U, (size_t)13U, &out); + lhs, rhs, libcrux_secrets_int_public_integers_classify_27_39(zeta3), + (size_t)6U, &out); libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials( - lhs, rhs, -zeta3, (size_t)14U, (size_t)15U, &out); + lhs, rhs, libcrux_secrets_int_public_integers_classify_27_39(nzeta3), + (size_t)7U, &out); return out; } /** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_ntt_multiply_0d( +libcrux_ml_kem_vector_portable_ntt_multiply_b8( libcrux_ml_kem_vector_portable_vector_type_PortableVector *lhs, libcrux_ml_kem_vector_portable_vector_type_PortableVector *rhs, int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3) { @@ -7350,62 +6326,114 @@ static KRML_MUSTINLINE void libcrux_ml_kem_vector_portable_serialize_serialize_1( libcrux_ml_kem_vector_portable_vector_type_PortableVector v, uint8_t ret[2U]) { - uint8_t result[2U] = {0U}; - for (size_t i = (size_t)0U; i < (size_t)8U; i++) { - size_t i0 = i; - size_t uu____0 = (size_t)0U; - result[uu____0] = (uint32_t)result[uu____0] | - (uint32_t)(uint8_t)v.elements[i0] << (uint32_t)i0; - } - for (size_t i = (size_t)8U; i < (size_t)16U; i++) { - size_t i0 = i; - size_t uu____1 = (size_t)1U; - result[uu____1] = - (uint32_t)result[uu____1] | (uint32_t)(uint8_t)v.elements[i0] - << (uint32_t)(i0 - (size_t)8U); - } - memcpy(ret, result, (size_t)2U * sizeof(uint8_t)); + uint8_t result0 = + (((((((uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[0U]) | + (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[1U]) << 1U) | + (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[2U]) << 2U) | + (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[3U]) << 3U) | + (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[4U]) << 4U) | + (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[5U]) << 5U) | + (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[6U]) << 6U) | + (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[7U]) << 7U; + uint8_t result1 = + (((((((uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[8U]) | + (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[9U]) << 1U) | + (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[10U]) << 2U) | + (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[11U]) << 3U) | + (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[12U]) << 4U) | + (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[13U]) << 5U) | + (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[14U]) << 6U) | + (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[15U]) << 7U; + ret[0U] = result0; + ret[1U] = result1; +} + +static inline void libcrux_ml_kem_vector_portable_serialize_1( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a, + uint8_t ret[2U]) { + uint8_t ret0[2U]; + libcrux_ml_kem_vector_portable_serialize_serialize_1(a, ret0); + libcrux_secrets_int_public_integers_declassify_d8_d4(ret0, ret); } /** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} */ -static inline void libcrux_ml_kem_vector_portable_serialize_1_0d( +static inline void libcrux_ml_kem_vector_portable_serialize_1_b8( libcrux_ml_kem_vector_portable_vector_type_PortableVector a, uint8_t ret[2U]) { - libcrux_ml_kem_vector_portable_serialize_serialize_1(a, ret); + libcrux_ml_kem_vector_portable_serialize_1(a, ret); } static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector libcrux_ml_kem_vector_portable_serialize_deserialize_1(Eurydice_slice v) { - libcrux_ml_kem_vector_portable_vector_type_PortableVector result = - libcrux_ml_kem_vector_portable_vector_type_zero(); - for (size_t i = (size_t)0U; i < (size_t)8U; i++) { - size_t i0 = i; - result.elements[i0] = (int16_t)((uint32_t)Eurydice_slice_index( - v, (size_t)0U, uint8_t, uint8_t *) >> - (uint32_t)i0 & - 1U); - } - for (size_t i = (size_t)8U; - i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { - size_t i0 = i; - result.elements[i0] = (int16_t)((uint32_t)Eurydice_slice_index( - v, (size_t)1U, uint8_t, uint8_t *) >> - (uint32_t)(i0 - (size_t)8U) & - 1U); - } - return result; + int16_t result0 = libcrux_secrets_int_as_i16_59( + (uint32_t)Eurydice_slice_index(v, (size_t)0U, uint8_t, uint8_t *) & 1U); + int16_t result1 = libcrux_secrets_int_as_i16_59( + (uint32_t)Eurydice_slice_index(v, (size_t)0U, uint8_t, uint8_t *) >> 1U & + 1U); + int16_t result2 = libcrux_secrets_int_as_i16_59( + (uint32_t)Eurydice_slice_index(v, (size_t)0U, uint8_t, uint8_t *) >> 2U & + 1U); + int16_t result3 = libcrux_secrets_int_as_i16_59( + (uint32_t)Eurydice_slice_index(v, (size_t)0U, uint8_t, uint8_t *) >> 3U & + 1U); + int16_t result4 = libcrux_secrets_int_as_i16_59( + (uint32_t)Eurydice_slice_index(v, (size_t)0U, uint8_t, uint8_t *) >> 4U & + 1U); + int16_t result5 = libcrux_secrets_int_as_i16_59( + (uint32_t)Eurydice_slice_index(v, (size_t)0U, uint8_t, uint8_t *) >> 5U & + 1U); + int16_t result6 = libcrux_secrets_int_as_i16_59( + (uint32_t)Eurydice_slice_index(v, (size_t)0U, uint8_t, uint8_t *) >> 6U & + 1U); + int16_t result7 = libcrux_secrets_int_as_i16_59( + (uint32_t)Eurydice_slice_index(v, (size_t)0U, uint8_t, uint8_t *) >> 7U & + 1U); + int16_t result8 = libcrux_secrets_int_as_i16_59( + (uint32_t)Eurydice_slice_index(v, (size_t)1U, uint8_t, uint8_t *) & 1U); + int16_t result9 = libcrux_secrets_int_as_i16_59( + (uint32_t)Eurydice_slice_index(v, (size_t)1U, uint8_t, uint8_t *) >> 1U & + 1U); + int16_t result10 = libcrux_secrets_int_as_i16_59( + (uint32_t)Eurydice_slice_index(v, (size_t)1U, uint8_t, uint8_t *) >> 2U & + 1U); + int16_t result11 = libcrux_secrets_int_as_i16_59( + (uint32_t)Eurydice_slice_index(v, (size_t)1U, uint8_t, uint8_t *) >> 3U & + 1U); + int16_t result12 = libcrux_secrets_int_as_i16_59( + (uint32_t)Eurydice_slice_index(v, (size_t)1U, uint8_t, uint8_t *) >> 4U & + 1U); + int16_t result13 = libcrux_secrets_int_as_i16_59( + (uint32_t)Eurydice_slice_index(v, (size_t)1U, uint8_t, uint8_t *) >> 5U & + 1U); + int16_t result14 = libcrux_secrets_int_as_i16_59( + (uint32_t)Eurydice_slice_index(v, (size_t)1U, uint8_t, uint8_t *) >> 6U & + 1U); + int16_t result15 = libcrux_secrets_int_as_i16_59( + (uint32_t)Eurydice_slice_index(v, (size_t)1U, uint8_t, uint8_t *) >> 7U & + 1U); + return ( + KRML_CLITERAL(libcrux_ml_kem_vector_portable_vector_type_PortableVector){ + .elements = {result0, result1, result2, result3, result4, result5, + result6, result7, result8, result9, result10, result11, + result12, result13, result14, result15}}); +} + +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_deserialize_1(Eurydice_slice a) { + return libcrux_ml_kem_vector_portable_serialize_deserialize_1( + libcrux_secrets_int_classify_public_classify_ref_9b_90(a)); } /** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_deserialize_1_0d(Eurydice_slice a) { - return libcrux_ml_kem_vector_portable_serialize_deserialize_1(a); +libcrux_ml_kem_vector_portable_deserialize_1_b8(Eurydice_slice a) { + return libcrux_ml_kem_vector_portable_deserialize_1(a); } typedef struct uint8_t_x4_s { @@ -7417,27 +6445,27 @@ typedef struct uint8_t_x4_s { static KRML_MUSTINLINE uint8_t_x4 libcrux_ml_kem_vector_portable_serialize_serialize_4_int(Eurydice_slice v) { - uint8_t result0 = - (uint32_t)(uint8_t)Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *) - << 4U | - (uint32_t)(uint8_t)Eurydice_slice_index(v, (size_t)0U, int16_t, - int16_t *); - uint8_t result1 = - (uint32_t)(uint8_t)Eurydice_slice_index(v, (size_t)3U, int16_t, int16_t *) - << 4U | - (uint32_t)(uint8_t)Eurydice_slice_index(v, (size_t)2U, int16_t, - int16_t *); - uint8_t result2 = - (uint32_t)(uint8_t)Eurydice_slice_index(v, (size_t)5U, int16_t, int16_t *) - << 4U | - (uint32_t)(uint8_t)Eurydice_slice_index(v, (size_t)4U, int16_t, - int16_t *); - uint8_t result3 = - (uint32_t)(uint8_t)Eurydice_slice_index(v, (size_t)7U, int16_t, int16_t *) - << 4U | - (uint32_t)(uint8_t)Eurydice_slice_index(v, (size_t)6U, int16_t, - int16_t *); - return (CLITERAL(uint8_t_x4){ + uint8_t result0 = (uint32_t)libcrux_secrets_int_as_u8_f5( + Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *)) + << 4U | + (uint32_t)libcrux_secrets_int_as_u8_f5(Eurydice_slice_index( + v, (size_t)0U, int16_t, int16_t *)); + uint8_t result1 = (uint32_t)libcrux_secrets_int_as_u8_f5( + Eurydice_slice_index(v, (size_t)3U, int16_t, int16_t *)) + << 4U | + (uint32_t)libcrux_secrets_int_as_u8_f5(Eurydice_slice_index( + v, (size_t)2U, int16_t, int16_t *)); + uint8_t result2 = (uint32_t)libcrux_secrets_int_as_u8_f5( + Eurydice_slice_index(v, (size_t)5U, int16_t, int16_t *)) + << 4U | + (uint32_t)libcrux_secrets_int_as_u8_f5(Eurydice_slice_index( + v, (size_t)4U, int16_t, int16_t *)); + uint8_t result3 = (uint32_t)libcrux_secrets_int_as_u8_f5( + Eurydice_slice_index(v, (size_t)7U, int16_t, int16_t *)) + << 4U | + (uint32_t)libcrux_secrets_int_as_u8_f5(Eurydice_slice_index( + v, (size_t)6U, int16_t, int16_t *)); + return (KRML_CLITERAL(uint8_t_x4){ .fst = result0, .snd = result1, .thd = result2, .f3 = result3}); } @@ -7447,109 +6475,107 @@ libcrux_ml_kem_vector_portable_serialize_serialize_4( uint8_t ret[8U]) { uint8_t_x4 result0_3 = libcrux_ml_kem_vector_portable_serialize_serialize_4_int( - Eurydice_array_to_subslice2(v.elements, (size_t)0U, (size_t)8U, - int16_t)); + Eurydice_array_to_subslice3(v.elements, (size_t)0U, (size_t)8U, + int16_t *)); uint8_t_x4 result4_7 = libcrux_ml_kem_vector_portable_serialize_serialize_4_int( - Eurydice_array_to_subslice2(v.elements, (size_t)8U, (size_t)16U, - int16_t)); - uint8_t result[8U] = {0U}; - result[0U] = result0_3.fst; - result[1U] = result0_3.snd; - result[2U] = result0_3.thd; - result[3U] = result0_3.f3; - result[4U] = result4_7.fst; - result[5U] = result4_7.snd; - result[6U] = result4_7.thd; - result[7U] = result4_7.f3; - memcpy(ret, result, (size_t)8U * sizeof(uint8_t)); + Eurydice_array_to_subslice3(v.elements, (size_t)8U, (size_t)16U, + int16_t *)); + ret[0U] = result0_3.fst; + ret[1U] = result0_3.snd; + ret[2U] = result0_3.thd; + ret[3U] = result0_3.f3; + ret[4U] = result4_7.fst; + ret[5U] = result4_7.snd; + ret[6U] = result4_7.thd; + ret[7U] = result4_7.f3; +} + +static inline void libcrux_ml_kem_vector_portable_serialize_4( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a, + uint8_t ret[8U]) { + uint8_t ret0[8U]; + libcrux_ml_kem_vector_portable_serialize_serialize_4(a, ret0); + libcrux_secrets_int_public_integers_declassify_d8_76(ret0, ret); } /** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} */ -static inline void libcrux_ml_kem_vector_portable_serialize_4_0d( +static inline void libcrux_ml_kem_vector_portable_serialize_4_b8( libcrux_ml_kem_vector_portable_vector_type_PortableVector a, uint8_t ret[8U]) { - libcrux_ml_kem_vector_portable_serialize_serialize_4(a, ret); + libcrux_ml_kem_vector_portable_serialize_4(a, ret); } static KRML_MUSTINLINE int16_t_x8 libcrux_ml_kem_vector_portable_serialize_deserialize_4_int( Eurydice_slice bytes) { - int16_t v0 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)0U, - uint8_t, uint8_t *) & - 15U); - int16_t v1 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)0U, - uint8_t, uint8_t *) >> - 4U & - 15U); - int16_t v2 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)1U, - uint8_t, uint8_t *) & - 15U); - int16_t v3 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)1U, - uint8_t, uint8_t *) >> - 4U & - 15U); - int16_t v4 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)2U, - uint8_t, uint8_t *) & - 15U); - int16_t v5 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)2U, - uint8_t, uint8_t *) >> - 4U & - 15U); - int16_t v6 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)3U, - uint8_t, uint8_t *) & - 15U); - int16_t v7 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)3U, - uint8_t, uint8_t *) >> - 4U & - 15U); - return (CLITERAL(int16_t_x8){.fst = v0, - .snd = v1, - .thd = v2, - .f3 = v3, - .f4 = v4, - .f5 = v5, - .f6 = v6, - .f7 = v7}); + int16_t v0 = libcrux_secrets_int_as_i16_59( + (uint32_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *) & + 15U); + int16_t v1 = libcrux_secrets_int_as_i16_59( + (uint32_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *) >> + 4U & + 15U); + int16_t v2 = libcrux_secrets_int_as_i16_59( + (uint32_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *) & + 15U); + int16_t v3 = libcrux_secrets_int_as_i16_59( + (uint32_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *) >> + 4U & + 15U); + int16_t v4 = libcrux_secrets_int_as_i16_59( + (uint32_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *) & + 15U); + int16_t v5 = libcrux_secrets_int_as_i16_59( + (uint32_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *) >> + 4U & + 15U); + int16_t v6 = libcrux_secrets_int_as_i16_59( + (uint32_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *) & + 15U); + int16_t v7 = libcrux_secrets_int_as_i16_59( + (uint32_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *) >> + 4U & + 15U); + return (KRML_CLITERAL(int16_t_x8){.fst = v0, + .snd = v1, + .thd = v2, + .f3 = v3, + .f4 = v4, + .f5 = v5, + .f6 = v6, + .f7 = v7}); } static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector libcrux_ml_kem_vector_portable_serialize_deserialize_4(Eurydice_slice bytes) { int16_t_x8 v0_7 = libcrux_ml_kem_vector_portable_serialize_deserialize_4_int( - Eurydice_slice_subslice2(bytes, (size_t)0U, (size_t)4U, uint8_t)); + Eurydice_slice_subslice3(bytes, (size_t)0U, (size_t)4U, uint8_t *)); int16_t_x8 v8_15 = libcrux_ml_kem_vector_portable_serialize_deserialize_4_int( - Eurydice_slice_subslice2(bytes, (size_t)4U, (size_t)8U, uint8_t)); - libcrux_ml_kem_vector_portable_vector_type_PortableVector v = - libcrux_ml_kem_vector_portable_vector_type_zero(); - v.elements[0U] = v0_7.fst; - v.elements[1U] = v0_7.snd; - v.elements[2U] = v0_7.thd; - v.elements[3U] = v0_7.f3; - v.elements[4U] = v0_7.f4; - v.elements[5U] = v0_7.f5; - v.elements[6U] = v0_7.f6; - v.elements[7U] = v0_7.f7; - v.elements[8U] = v8_15.fst; - v.elements[9U] = v8_15.snd; - v.elements[10U] = v8_15.thd; - v.elements[11U] = v8_15.f3; - v.elements[12U] = v8_15.f4; - v.elements[13U] = v8_15.f5; - v.elements[14U] = v8_15.f6; - v.elements[15U] = v8_15.f7; - return v; -} - -/** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} + Eurydice_slice_subslice3(bytes, (size_t)4U, (size_t)8U, uint8_t *)); + return ( + KRML_CLITERAL(libcrux_ml_kem_vector_portable_vector_type_PortableVector){ + .elements = {v0_7.fst, v0_7.snd, v0_7.thd, v0_7.f3, v0_7.f4, v0_7.f5, + v0_7.f6, v0_7.f7, v8_15.fst, v8_15.snd, v8_15.thd, + v8_15.f3, v8_15.f4, v8_15.f5, v8_15.f6, v8_15.f7}}); +} + +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_deserialize_4(Eurydice_slice a) { + return libcrux_ml_kem_vector_portable_serialize_deserialize_4( + libcrux_secrets_int_classify_public_classify_ref_9b_90(a)); +} + +/** +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_deserialize_4_0d(Eurydice_slice a) { - return libcrux_ml_kem_vector_portable_serialize_deserialize_4(a); +libcrux_ml_kem_vector_portable_deserialize_4_b8(Eurydice_slice a) { + return libcrux_ml_kem_vector_portable_deserialize_4(a); } typedef struct uint8_t_x5_s { @@ -7561,184 +6587,34 @@ typedef struct uint8_t_x5_s { } uint8_t_x5; static KRML_MUSTINLINE uint8_t_x5 -libcrux_ml_kem_vector_portable_serialize_serialize_5_int(Eurydice_slice v) { - uint8_t r0 = - (uint8_t)(Eurydice_slice_index(v, (size_t)0U, int16_t, int16_t *) | - Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *) << 5U); +libcrux_ml_kem_vector_portable_serialize_serialize_10_int(Eurydice_slice v) { + uint8_t r0 = libcrux_secrets_int_as_u8_f5( + Eurydice_slice_index(v, (size_t)0U, int16_t, int16_t *) & (int16_t)255); uint8_t r1 = - (uint8_t)((Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *) >> 3U | - Eurydice_slice_index(v, (size_t)2U, int16_t, int16_t *) - << 2U) | - Eurydice_slice_index(v, (size_t)3U, int16_t, int16_t *) << 7U); + (uint32_t)libcrux_secrets_int_as_u8_f5( + Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *) & (int16_t)63) + << 2U | + (uint32_t)libcrux_secrets_int_as_u8_f5( + Eurydice_slice_index(v, (size_t)0U, int16_t, int16_t *) >> 8U & + (int16_t)3); uint8_t r2 = - (uint8_t)(Eurydice_slice_index(v, (size_t)3U, int16_t, int16_t *) >> 1U | - Eurydice_slice_index(v, (size_t)4U, int16_t, int16_t *) << 4U); + (uint32_t)libcrux_secrets_int_as_u8_f5( + Eurydice_slice_index(v, (size_t)2U, int16_t, int16_t *) & (int16_t)15) + << 4U | + (uint32_t)libcrux_secrets_int_as_u8_f5( + Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *) >> 6U & + (int16_t)15); uint8_t r3 = - (uint8_t)((Eurydice_slice_index(v, (size_t)4U, int16_t, int16_t *) >> 4U | - Eurydice_slice_index(v, (size_t)5U, int16_t, int16_t *) - << 1U) | - Eurydice_slice_index(v, (size_t)6U, int16_t, int16_t *) << 6U); - uint8_t r4 = - (uint8_t)(Eurydice_slice_index(v, (size_t)6U, int16_t, int16_t *) >> 2U | - Eurydice_slice_index(v, (size_t)7U, int16_t, int16_t *) << 3U); - return (CLITERAL(uint8_t_x5){ - .fst = r0, .snd = r1, .thd = r2, .f3 = r3, .f4 = r4}); -} - -static KRML_MUSTINLINE void -libcrux_ml_kem_vector_portable_serialize_serialize_5( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v, - uint8_t ret[10U]) { - uint8_t_x5 r0_4 = libcrux_ml_kem_vector_portable_serialize_serialize_5_int( - Eurydice_array_to_subslice2(v.elements, (size_t)0U, (size_t)8U, int16_t)); - uint8_t_x5 r5_9 = libcrux_ml_kem_vector_portable_serialize_serialize_5_int( - Eurydice_array_to_subslice2(v.elements, (size_t)8U, (size_t)16U, - int16_t)); - uint8_t result[10U] = {0U}; - result[0U] = r0_4.fst; - result[1U] = r0_4.snd; - result[2U] = r0_4.thd; - result[3U] = r0_4.f3; - result[4U] = r0_4.f4; - result[5U] = r5_9.fst; - result[6U] = r5_9.snd; - result[7U] = r5_9.thd; - result[8U] = r5_9.f3; - result[9U] = r5_9.f4; - memcpy(ret, result, (size_t)10U * sizeof(uint8_t)); -} - -/** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} -*/ -static inline void libcrux_ml_kem_vector_portable_serialize_5_0d( - libcrux_ml_kem_vector_portable_vector_type_PortableVector a, - uint8_t ret[10U]) { - libcrux_ml_kem_vector_portable_serialize_serialize_5(a, ret); -} - -static KRML_MUSTINLINE int16_t_x8 -libcrux_ml_kem_vector_portable_serialize_deserialize_5_int( - Eurydice_slice bytes) { - int16_t v0 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)0U, - uint8_t, uint8_t *) & - 31U); - int16_t v1 = (int16_t)(((uint32_t)Eurydice_slice_index(bytes, (size_t)1U, - uint8_t, uint8_t *) & - 3U) << 3U | - (uint32_t)Eurydice_slice_index(bytes, (size_t)0U, - uint8_t, uint8_t *) >> - 5U); - int16_t v2 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)1U, - uint8_t, uint8_t *) >> - 2U & - 31U); - int16_t v3 = (int16_t)(((uint32_t)Eurydice_slice_index(bytes, (size_t)2U, - uint8_t, uint8_t *) & - 15U) - << 1U | - (uint32_t)Eurydice_slice_index(bytes, (size_t)1U, - uint8_t, uint8_t *) >> - 7U); - int16_t v4 = (int16_t)(((uint32_t)Eurydice_slice_index(bytes, (size_t)3U, - uint8_t, uint8_t *) & - 1U) << 4U | - (uint32_t)Eurydice_slice_index(bytes, (size_t)2U, - uint8_t, uint8_t *) >> - 4U); - int16_t v5 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)3U, - uint8_t, uint8_t *) >> - 1U & - 31U); - int16_t v6 = (int16_t)(((uint32_t)Eurydice_slice_index(bytes, (size_t)4U, - uint8_t, uint8_t *) & - 7U) << 2U | - (uint32_t)Eurydice_slice_index(bytes, (size_t)3U, - uint8_t, uint8_t *) >> - 6U); - int16_t v7 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)4U, - uint8_t, uint8_t *) >> - 3U); - return (CLITERAL(int16_t_x8){.fst = v0, - .snd = v1, - .thd = v2, - .f3 = v3, - .f4 = v4, - .f5 = v5, - .f6 = v6, - .f7 = v7}); -} - -static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_serialize_deserialize_5(Eurydice_slice bytes) { - int16_t_x8 v0_7 = libcrux_ml_kem_vector_portable_serialize_deserialize_5_int( - Eurydice_slice_subslice2(bytes, (size_t)0U, (size_t)5U, uint8_t)); - int16_t_x8 v8_15 = libcrux_ml_kem_vector_portable_serialize_deserialize_5_int( - Eurydice_slice_subslice2(bytes, (size_t)5U, (size_t)10U, uint8_t)); - libcrux_ml_kem_vector_portable_vector_type_PortableVector v = - libcrux_ml_kem_vector_portable_vector_type_zero(); - v.elements[0U] = v0_7.fst; - v.elements[1U] = v0_7.snd; - v.elements[2U] = v0_7.thd; - v.elements[3U] = v0_7.f3; - v.elements[4U] = v0_7.f4; - v.elements[5U] = v0_7.f5; - v.elements[6U] = v0_7.f6; - v.elements[7U] = v0_7.f7; - v.elements[8U] = v8_15.fst; - v.elements[9U] = v8_15.snd; - v.elements[10U] = v8_15.thd; - v.elements[11U] = v8_15.f3; - v.elements[12U] = v8_15.f4; - v.elements[13U] = v8_15.f5; - v.elements[14U] = v8_15.f6; - v.elements[15U] = v8_15.f7; - return v; -} - -/** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} -*/ -static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_deserialize_5_0d(Eurydice_slice a) { - return libcrux_ml_kem_vector_portable_serialize_deserialize_5(a); -} - -static KRML_MUSTINLINE uint8_t_x5 -libcrux_ml_kem_vector_portable_serialize_serialize_10_int(Eurydice_slice v) { - uint8_t r0 = - (uint8_t)(Eurydice_slice_index(v, (size_t)0U, int16_t, int16_t *) & - (int16_t)255); - uint8_t r1 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)1U, int16_t, - int16_t *) & - (int16_t)63) - << 2U | - (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)0U, int16_t, - int16_t *) >> - 8U & - (int16_t)3); - uint8_t r2 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)2U, int16_t, - int16_t *) & - (int16_t)15) - << 4U | - (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)1U, int16_t, - int16_t *) >> - 6U & - (int16_t)15); - uint8_t r3 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)3U, int16_t, - int16_t *) & - (int16_t)3) - << 6U | - (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)2U, int16_t, - int16_t *) >> - 4U & - (int16_t)63); - uint8_t r4 = - (uint8_t)(Eurydice_slice_index(v, (size_t)3U, int16_t, int16_t *) >> 2U & - (int16_t)255); - return (CLITERAL(uint8_t_x5){ + (uint32_t)libcrux_secrets_int_as_u8_f5( + Eurydice_slice_index(v, (size_t)3U, int16_t, int16_t *) & (int16_t)3) + << 6U | + (uint32_t)libcrux_secrets_int_as_u8_f5( + Eurydice_slice_index(v, (size_t)2U, int16_t, int16_t *) >> 4U & + (int16_t)63); + uint8_t r4 = libcrux_secrets_int_as_u8_f5( + Eurydice_slice_index(v, (size_t)3U, int16_t, int16_t *) >> 2U & + (int16_t)255); + return (KRML_CLITERAL(uint8_t_x5){ .fst = r0, .snd = r1, .thd = r2, .f3 = r3, .f4 = r4}); } @@ -7747,143 +6623,159 @@ libcrux_ml_kem_vector_portable_serialize_serialize_10( libcrux_ml_kem_vector_portable_vector_type_PortableVector v, uint8_t ret[20U]) { uint8_t_x5 r0_4 = libcrux_ml_kem_vector_portable_serialize_serialize_10_int( - Eurydice_array_to_subslice2(v.elements, (size_t)0U, (size_t)4U, int16_t)); + Eurydice_array_to_subslice3(v.elements, (size_t)0U, (size_t)4U, + int16_t *)); uint8_t_x5 r5_9 = libcrux_ml_kem_vector_portable_serialize_serialize_10_int( - Eurydice_array_to_subslice2(v.elements, (size_t)4U, (size_t)8U, int16_t)); + Eurydice_array_to_subslice3(v.elements, (size_t)4U, (size_t)8U, + int16_t *)); uint8_t_x5 r10_14 = libcrux_ml_kem_vector_portable_serialize_serialize_10_int( - Eurydice_array_to_subslice2(v.elements, (size_t)8U, (size_t)12U, - int16_t)); + Eurydice_array_to_subslice3(v.elements, (size_t)8U, (size_t)12U, + int16_t *)); uint8_t_x5 r15_19 = libcrux_ml_kem_vector_portable_serialize_serialize_10_int( - Eurydice_array_to_subslice2(v.elements, (size_t)12U, (size_t)16U, - int16_t)); - uint8_t result[20U] = {0U}; - result[0U] = r0_4.fst; - result[1U] = r0_4.snd; - result[2U] = r0_4.thd; - result[3U] = r0_4.f3; - result[4U] = r0_4.f4; - result[5U] = r5_9.fst; - result[6U] = r5_9.snd; - result[7U] = r5_9.thd; - result[8U] = r5_9.f3; - result[9U] = r5_9.f4; - result[10U] = r10_14.fst; - result[11U] = r10_14.snd; - result[12U] = r10_14.thd; - result[13U] = r10_14.f3; - result[14U] = r10_14.f4; - result[15U] = r15_19.fst; - result[16U] = r15_19.snd; - result[17U] = r15_19.thd; - result[18U] = r15_19.f3; - result[19U] = r15_19.f4; - memcpy(ret, result, (size_t)20U * sizeof(uint8_t)); -} - -/** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} -*/ -static inline void libcrux_ml_kem_vector_portable_serialize_10_0d( + Eurydice_array_to_subslice3(v.elements, (size_t)12U, (size_t)16U, + int16_t *)); + ret[0U] = r0_4.fst; + ret[1U] = r0_4.snd; + ret[2U] = r0_4.thd; + ret[3U] = r0_4.f3; + ret[4U] = r0_4.f4; + ret[5U] = r5_9.fst; + ret[6U] = r5_9.snd; + ret[7U] = r5_9.thd; + ret[8U] = r5_9.f3; + ret[9U] = r5_9.f4; + ret[10U] = r10_14.fst; + ret[11U] = r10_14.snd; + ret[12U] = r10_14.thd; + ret[13U] = r10_14.f3; + ret[14U] = r10_14.f4; + ret[15U] = r15_19.fst; + ret[16U] = r15_19.snd; + ret[17U] = r15_19.thd; + ret[18U] = r15_19.f3; + ret[19U] = r15_19.f4; +} + +static inline void libcrux_ml_kem_vector_portable_serialize_10( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a, + uint8_t ret[20U]) { + uint8_t ret0[20U]; + libcrux_ml_kem_vector_portable_serialize_serialize_10(a, ret0); + libcrux_secrets_int_public_integers_declassify_d8_57(ret0, ret); +} + +/** +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} +*/ +static inline void libcrux_ml_kem_vector_portable_serialize_10_b8( libcrux_ml_kem_vector_portable_vector_type_PortableVector a, uint8_t ret[20U]) { - libcrux_ml_kem_vector_portable_serialize_serialize_10(a, ret); + libcrux_ml_kem_vector_portable_serialize_10(a, ret); } static KRML_MUSTINLINE int16_t_x8 libcrux_ml_kem_vector_portable_serialize_deserialize_10_int( Eurydice_slice bytes) { - int16_t r0 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *) & + int16_t r0 = libcrux_secrets_int_as_i16_f5( + (libcrux_secrets_int_as_i16_59( + Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *)) & (int16_t)3) << 8U | - ((int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *) & - (int16_t)255); - int16_t r1 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *) & + (libcrux_secrets_int_as_i16_59( + Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *)) & + (int16_t)255)); + int16_t r1 = libcrux_secrets_int_as_i16_f5( + (libcrux_secrets_int_as_i16_59( + Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *)) & (int16_t)15) << 6U | - (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *) >> - 2U; - int16_t r2 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *) & + libcrux_secrets_int_as_i16_59( + Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *)) >> + 2U); + int16_t r2 = libcrux_secrets_int_as_i16_f5( + (libcrux_secrets_int_as_i16_59( + Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *)) & (int16_t)63) << 4U | - (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *) >> - 4U; - int16_t r3 = - (int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *) + libcrux_secrets_int_as_i16_59( + Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *)) >> + 4U); + int16_t r3 = libcrux_secrets_int_as_i16_f5( + libcrux_secrets_int_as_i16_59( + Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *)) << 2U | - (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *) >> - 6U; - int16_t r4 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *) & + libcrux_secrets_int_as_i16_59( + Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *)) >> + 6U); + int16_t r4 = libcrux_secrets_int_as_i16_f5( + (libcrux_secrets_int_as_i16_59( + Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *)) & (int16_t)3) << 8U | - ((int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *) & - (int16_t)255); - int16_t r5 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *) & + (libcrux_secrets_int_as_i16_59( + Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *)) & + (int16_t)255)); + int16_t r5 = libcrux_secrets_int_as_i16_f5( + (libcrux_secrets_int_as_i16_59( + Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *)) & (int16_t)15) << 6U | - (int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *) >> - 2U; - int16_t r6 = - ((int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *) & + libcrux_secrets_int_as_i16_59( + Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *)) >> + 2U); + int16_t r6 = libcrux_secrets_int_as_i16_f5( + (libcrux_secrets_int_as_i16_59( + Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *)) & (int16_t)63) << 4U | - (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *) >> - 4U; - int16_t r7 = - (int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *) + libcrux_secrets_int_as_i16_59( + Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *)) >> + 4U); + int16_t r7 = libcrux_secrets_int_as_i16_f5( + libcrux_secrets_int_as_i16_59( + Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *)) << 2U | - (int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *) >> - 6U; - return (CLITERAL(int16_t_x8){.fst = r0, - .snd = r1, - .thd = r2, - .f3 = r3, - .f4 = r4, - .f5 = r5, - .f6 = r6, - .f7 = r7}); + libcrux_secrets_int_as_i16_59( + Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *)) >> + 6U); + return (KRML_CLITERAL(int16_t_x8){.fst = r0, + .snd = r1, + .thd = r2, + .f3 = r3, + .f4 = r4, + .f5 = r5, + .f6 = r6, + .f7 = r7}); } static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector libcrux_ml_kem_vector_portable_serialize_deserialize_10(Eurydice_slice bytes) { int16_t_x8 v0_7 = libcrux_ml_kem_vector_portable_serialize_deserialize_10_int( - Eurydice_slice_subslice2(bytes, (size_t)0U, (size_t)10U, uint8_t)); + Eurydice_slice_subslice3(bytes, (size_t)0U, (size_t)10U, uint8_t *)); int16_t_x8 v8_15 = libcrux_ml_kem_vector_portable_serialize_deserialize_10_int( - Eurydice_slice_subslice2(bytes, (size_t)10U, (size_t)20U, uint8_t)); - libcrux_ml_kem_vector_portable_vector_type_PortableVector v = - libcrux_ml_kem_vector_portable_vector_type_zero(); - v.elements[0U] = v0_7.fst; - v.elements[1U] = v0_7.snd; - v.elements[2U] = v0_7.thd; - v.elements[3U] = v0_7.f3; - v.elements[4U] = v0_7.f4; - v.elements[5U] = v0_7.f5; - v.elements[6U] = v0_7.f6; - v.elements[7U] = v0_7.f7; - v.elements[8U] = v8_15.fst; - v.elements[9U] = v8_15.snd; - v.elements[10U] = v8_15.thd; - v.elements[11U] = v8_15.f3; - v.elements[12U] = v8_15.f4; - v.elements[13U] = v8_15.f5; - v.elements[14U] = v8_15.f6; - v.elements[15U] = v8_15.f7; - return v; -} - -/** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} + Eurydice_slice_subslice3(bytes, (size_t)10U, (size_t)20U, uint8_t *)); + return ( + KRML_CLITERAL(libcrux_ml_kem_vector_portable_vector_type_PortableVector){ + .elements = {v0_7.fst, v0_7.snd, v0_7.thd, v0_7.f3, v0_7.f4, v0_7.f5, + v0_7.f6, v0_7.f7, v8_15.fst, v8_15.snd, v8_15.thd, + v8_15.f3, v8_15.f4, v8_15.f5, v8_15.f6, v8_15.f7}}); +} + +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_deserialize_10(Eurydice_slice a) { + return libcrux_ml_kem_vector_portable_serialize_deserialize_10( + libcrux_secrets_int_classify_public_classify_ref_9b_90(a)); +} + +/** +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_deserialize_10_0d(Eurydice_slice a) { - return libcrux_ml_kem_vector_portable_serialize_deserialize_10(a); +libcrux_ml_kem_vector_portable_deserialize_10_b8(Eurydice_slice a) { + return libcrux_ml_kem_vector_portable_deserialize_10(a); } typedef struct uint8_t_x3_s { @@ -7894,18 +6786,16 @@ typedef struct uint8_t_x3_s { static KRML_MUSTINLINE uint8_t_x3 libcrux_ml_kem_vector_portable_serialize_serialize_12_int(Eurydice_slice v) { - uint8_t r0 = - (uint8_t)(Eurydice_slice_index(v, (size_t)0U, int16_t, int16_t *) & - (int16_t)255); - uint8_t r1 = - (uint8_t)(Eurydice_slice_index(v, (size_t)0U, int16_t, int16_t *) >> 8U | - (Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *) & - (int16_t)15) - << 4U); - uint8_t r2 = - (uint8_t)(Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *) >> 4U & - (int16_t)255); - return (CLITERAL(uint8_t_x3){.fst = r0, .snd = r1, .thd = r2}); + uint8_t r0 = libcrux_secrets_int_as_u8_f5( + Eurydice_slice_index(v, (size_t)0U, int16_t, int16_t *) & (int16_t)255); + uint8_t r1 = libcrux_secrets_int_as_u8_f5( + Eurydice_slice_index(v, (size_t)0U, int16_t, int16_t *) >> 8U | + (Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *) & (int16_t)15) + << 4U); + uint8_t r2 = libcrux_secrets_int_as_u8_f5( + Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *) >> 4U & + (int16_t)255); + return (KRML_CLITERAL(uint8_t_x3){.fst = r0, .snd = r1, .thd = r2}); } static KRML_MUSTINLINE void @@ -7913,61 +6803,71 @@ libcrux_ml_kem_vector_portable_serialize_serialize_12( libcrux_ml_kem_vector_portable_vector_type_PortableVector v, uint8_t ret[24U]) { uint8_t_x3 r0_2 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int( - Eurydice_array_to_subslice2(v.elements, (size_t)0U, (size_t)2U, int16_t)); + Eurydice_array_to_subslice3(v.elements, (size_t)0U, (size_t)2U, + int16_t *)); uint8_t_x3 r3_5 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int( - Eurydice_array_to_subslice2(v.elements, (size_t)2U, (size_t)4U, int16_t)); + Eurydice_array_to_subslice3(v.elements, (size_t)2U, (size_t)4U, + int16_t *)); uint8_t_x3 r6_8 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int( - Eurydice_array_to_subslice2(v.elements, (size_t)4U, (size_t)6U, int16_t)); + Eurydice_array_to_subslice3(v.elements, (size_t)4U, (size_t)6U, + int16_t *)); uint8_t_x3 r9_11 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int( - Eurydice_array_to_subslice2(v.elements, (size_t)6U, (size_t)8U, int16_t)); + Eurydice_array_to_subslice3(v.elements, (size_t)6U, (size_t)8U, + int16_t *)); uint8_t_x3 r12_14 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int( - Eurydice_array_to_subslice2(v.elements, (size_t)8U, (size_t)10U, - int16_t)); + Eurydice_array_to_subslice3(v.elements, (size_t)8U, (size_t)10U, + int16_t *)); uint8_t_x3 r15_17 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int( - Eurydice_array_to_subslice2(v.elements, (size_t)10U, (size_t)12U, - int16_t)); + Eurydice_array_to_subslice3(v.elements, (size_t)10U, (size_t)12U, + int16_t *)); uint8_t_x3 r18_20 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int( - Eurydice_array_to_subslice2(v.elements, (size_t)12U, (size_t)14U, - int16_t)); + Eurydice_array_to_subslice3(v.elements, (size_t)12U, (size_t)14U, + int16_t *)); uint8_t_x3 r21_23 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int( - Eurydice_array_to_subslice2(v.elements, (size_t)14U, (size_t)16U, - int16_t)); - uint8_t result[24U] = {0U}; - result[0U] = r0_2.fst; - result[1U] = r0_2.snd; - result[2U] = r0_2.thd; - result[3U] = r3_5.fst; - result[4U] = r3_5.snd; - result[5U] = r3_5.thd; - result[6U] = r6_8.fst; - result[7U] = r6_8.snd; - result[8U] = r6_8.thd; - result[9U] = r9_11.fst; - result[10U] = r9_11.snd; - result[11U] = r9_11.thd; - result[12U] = r12_14.fst; - result[13U] = r12_14.snd; - result[14U] = r12_14.thd; - result[15U] = r15_17.fst; - result[16U] = r15_17.snd; - result[17U] = r15_17.thd; - result[18U] = r18_20.fst; - result[19U] = r18_20.snd; - result[20U] = r18_20.thd; - result[21U] = r21_23.fst; - result[22U] = r21_23.snd; - result[23U] = r21_23.thd; - memcpy(ret, result, (size_t)24U * sizeof(uint8_t)); -} - -/** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} -*/ -static inline void libcrux_ml_kem_vector_portable_serialize_12_0d( + Eurydice_array_to_subslice3(v.elements, (size_t)14U, (size_t)16U, + int16_t *)); + ret[0U] = r0_2.fst; + ret[1U] = r0_2.snd; + ret[2U] = r0_2.thd; + ret[3U] = r3_5.fst; + ret[4U] = r3_5.snd; + ret[5U] = r3_5.thd; + ret[6U] = r6_8.fst; + ret[7U] = r6_8.snd; + ret[8U] = r6_8.thd; + ret[9U] = r9_11.fst; + ret[10U] = r9_11.snd; + ret[11U] = r9_11.thd; + ret[12U] = r12_14.fst; + ret[13U] = r12_14.snd; + ret[14U] = r12_14.thd; + ret[15U] = r15_17.fst; + ret[16U] = r15_17.snd; + ret[17U] = r15_17.thd; + ret[18U] = r18_20.fst; + ret[19U] = r18_20.snd; + ret[20U] = r18_20.thd; + ret[21U] = r21_23.fst; + ret[22U] = r21_23.snd; + ret[23U] = r21_23.thd; +} + +static inline void libcrux_ml_kem_vector_portable_serialize_12( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a, + uint8_t ret[24U]) { + uint8_t ret0[24U]; + libcrux_ml_kem_vector_portable_serialize_serialize_12(a, ret0); + libcrux_secrets_int_public_integers_declassify_d8_d2(ret0, ret); +} + +/** +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} +*/ +static inline void libcrux_ml_kem_vector_portable_serialize_12_b8( libcrux_ml_kem_vector_portable_vector_type_PortableVector a, uint8_t ret[24U]) { - libcrux_ml_kem_vector_portable_serialize_serialize_12(a, ret); + libcrux_ml_kem_vector_portable_serialize_12(a, ret); } typedef struct int16_t_x2_s { @@ -7978,66 +6878,59 @@ typedef struct int16_t_x2_s { static KRML_MUSTINLINE int16_t_x2 libcrux_ml_kem_vector_portable_serialize_deserialize_12_int( Eurydice_slice bytes) { - int16_t byte0 = - (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *); - int16_t byte1 = - (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *); - int16_t byte2 = - (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *); + int16_t byte0 = libcrux_secrets_int_as_i16_59( + Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *)); + int16_t byte1 = libcrux_secrets_int_as_i16_59( + Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *)); + int16_t byte2 = libcrux_secrets_int_as_i16_59( + Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *)); int16_t r0 = (byte1 & (int16_t)15) << 8U | (byte0 & (int16_t)255); int16_t r1 = byte2 << 4U | (byte1 >> 4U & (int16_t)15); - return (CLITERAL(int16_t_x2){.fst = r0, .snd = r1}); + return (KRML_CLITERAL(int16_t_x2){.fst = r0, .snd = r1}); } static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector libcrux_ml_kem_vector_portable_serialize_deserialize_12(Eurydice_slice bytes) { int16_t_x2 v0_1 = libcrux_ml_kem_vector_portable_serialize_deserialize_12_int( - Eurydice_slice_subslice2(bytes, (size_t)0U, (size_t)3U, uint8_t)); + Eurydice_slice_subslice3(bytes, (size_t)0U, (size_t)3U, uint8_t *)); int16_t_x2 v2_3 = libcrux_ml_kem_vector_portable_serialize_deserialize_12_int( - Eurydice_slice_subslice2(bytes, (size_t)3U, (size_t)6U, uint8_t)); + Eurydice_slice_subslice3(bytes, (size_t)3U, (size_t)6U, uint8_t *)); int16_t_x2 v4_5 = libcrux_ml_kem_vector_portable_serialize_deserialize_12_int( - Eurydice_slice_subslice2(bytes, (size_t)6U, (size_t)9U, uint8_t)); + Eurydice_slice_subslice3(bytes, (size_t)6U, (size_t)9U, uint8_t *)); int16_t_x2 v6_7 = libcrux_ml_kem_vector_portable_serialize_deserialize_12_int( - Eurydice_slice_subslice2(bytes, (size_t)9U, (size_t)12U, uint8_t)); + Eurydice_slice_subslice3(bytes, (size_t)9U, (size_t)12U, uint8_t *)); int16_t_x2 v8_9 = libcrux_ml_kem_vector_portable_serialize_deserialize_12_int( - Eurydice_slice_subslice2(bytes, (size_t)12U, (size_t)15U, uint8_t)); + Eurydice_slice_subslice3(bytes, (size_t)12U, (size_t)15U, uint8_t *)); int16_t_x2 v10_11 = libcrux_ml_kem_vector_portable_serialize_deserialize_12_int( - Eurydice_slice_subslice2(bytes, (size_t)15U, (size_t)18U, uint8_t)); + Eurydice_slice_subslice3(bytes, (size_t)15U, (size_t)18U, uint8_t *)); int16_t_x2 v12_13 = libcrux_ml_kem_vector_portable_serialize_deserialize_12_int( - Eurydice_slice_subslice2(bytes, (size_t)18U, (size_t)21U, uint8_t)); + Eurydice_slice_subslice3(bytes, (size_t)18U, (size_t)21U, uint8_t *)); int16_t_x2 v14_15 = libcrux_ml_kem_vector_portable_serialize_deserialize_12_int( - Eurydice_slice_subslice2(bytes, (size_t)21U, (size_t)24U, uint8_t)); - libcrux_ml_kem_vector_portable_vector_type_PortableVector re = - libcrux_ml_kem_vector_portable_vector_type_zero(); - re.elements[0U] = v0_1.fst; - re.elements[1U] = v0_1.snd; - re.elements[2U] = v2_3.fst; - re.elements[3U] = v2_3.snd; - re.elements[4U] = v4_5.fst; - re.elements[5U] = v4_5.snd; - re.elements[6U] = v6_7.fst; - re.elements[7U] = v6_7.snd; - re.elements[8U] = v8_9.fst; - re.elements[9U] = v8_9.snd; - re.elements[10U] = v10_11.fst; - re.elements[11U] = v10_11.snd; - re.elements[12U] = v12_13.fst; - re.elements[13U] = v12_13.snd; - re.elements[14U] = v14_15.fst; - re.elements[15U] = v14_15.snd; - return re; + Eurydice_slice_subslice3(bytes, (size_t)21U, (size_t)24U, uint8_t *)); + return ( + KRML_CLITERAL(libcrux_ml_kem_vector_portable_vector_type_PortableVector){ + .elements = {v0_1.fst, v0_1.snd, v2_3.fst, v2_3.snd, v4_5.fst, + v4_5.snd, v6_7.fst, v6_7.snd, v8_9.fst, v8_9.snd, + v10_11.fst, v10_11.snd, v12_13.fst, v12_13.snd, + v14_15.fst, v14_15.snd}}); +} + +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_deserialize_12(Eurydice_slice a) { + return libcrux_ml_kem_vector_portable_serialize_deserialize_12( + libcrux_secrets_int_classify_public_classify_ref_9b_90(a)); } /** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_deserialize_12_0d(Eurydice_slice a) { - return libcrux_ml_kem_vector_portable_serialize_deserialize_12(a); +libcrux_ml_kem_vector_portable_deserialize_12_b8(Eurydice_slice a) { + return libcrux_ml_kem_vector_portable_deserialize_12(a); } static KRML_MUSTINLINE size_t @@ -8055,46 +6948,16 @@ libcrux_ml_kem_vector_portable_sampling_rej_sample(Eurydice_slice a, uint8_t, uint8_t *); int16_t d1 = (b2 & (int16_t)15) << 8U | b1; int16_t d2 = b3 << 4U | b2 >> 4U; - bool uu____0; - int16_t uu____1; - bool uu____2; - size_t uu____3; - int16_t uu____4; - size_t uu____5; - int16_t uu____6; if (d1 < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS) { if (sampled < (size_t)16U) { Eurydice_slice_index(result, sampled, int16_t, int16_t *) = d1; sampled++; - uu____1 = d2; - uu____6 = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; - uu____0 = uu____1 < uu____6; - if (uu____0) { - uu____3 = sampled; - uu____2 = uu____3 < (size_t)16U; - if (uu____2) { - uu____4 = d2; - uu____5 = sampled; - Eurydice_slice_index(result, uu____5, int16_t, int16_t *) = uu____4; - sampled++; - continue; - } - } - continue; } } - uu____1 = d2; - uu____6 = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; - uu____0 = uu____1 < uu____6; - if (uu____0) { - uu____3 = sampled; - uu____2 = uu____3 < (size_t)16U; - if (uu____2) { - uu____4 = d2; - uu____5 = sampled; - Eurydice_slice_index(result, uu____5, int16_t, int16_t *) = uu____4; + if (d2 < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS) { + if (sampled < (size_t)16U) { + Eurydice_slice_index(result, sampled, int16_t, int16_t *) = d2; sampled++; - continue; } } } @@ -8102,45 +6965,45 @@ libcrux_ml_kem_vector_portable_sampling_rej_sample(Eurydice_slice a, } /** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} */ -static inline size_t libcrux_ml_kem_vector_portable_rej_sample_0d( +static inline size_t libcrux_ml_kem_vector_portable_rej_sample_b8( Eurydice_slice a, Eurydice_slice out) { return libcrux_ml_kem_vector_portable_sampling_rej_sample(a, out); } -#define LIBCRUX_ML_KEM_MLKEM768_VECTOR_U_COMPRESSION_FACTOR_768 ((size_t)10U) +#define LIBCRUX_ML_KEM_MLKEM768_VECTOR_U_COMPRESSION_FACTOR ((size_t)10U) -#define LIBCRUX_ML_KEM_MLKEM768_C1_BLOCK_SIZE_768 \ +#define LIBCRUX_ML_KEM_MLKEM768_C1_BLOCK_SIZE \ (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ - LIBCRUX_ML_KEM_MLKEM768_VECTOR_U_COMPRESSION_FACTOR_768 / (size_t)8U) + LIBCRUX_ML_KEM_MLKEM768_VECTOR_U_COMPRESSION_FACTOR / (size_t)8U) -#define LIBCRUX_ML_KEM_MLKEM768_RANK_768 ((size_t)3U) +#define LIBCRUX_ML_KEM_MLKEM768_RANK ((size_t)3U) -#define LIBCRUX_ML_KEM_MLKEM768_C1_SIZE_768 \ - (LIBCRUX_ML_KEM_MLKEM768_C1_BLOCK_SIZE_768 * LIBCRUX_ML_KEM_MLKEM768_RANK_768) +#define LIBCRUX_ML_KEM_MLKEM768_C1_SIZE \ + (LIBCRUX_ML_KEM_MLKEM768_C1_BLOCK_SIZE * LIBCRUX_ML_KEM_MLKEM768_RANK) -#define LIBCRUX_ML_KEM_MLKEM768_VECTOR_V_COMPRESSION_FACTOR_768 ((size_t)4U) +#define LIBCRUX_ML_KEM_MLKEM768_VECTOR_V_COMPRESSION_FACTOR ((size_t)4U) -#define LIBCRUX_ML_KEM_MLKEM768_C2_SIZE_768 \ +#define LIBCRUX_ML_KEM_MLKEM768_C2_SIZE \ (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ - LIBCRUX_ML_KEM_MLKEM768_VECTOR_V_COMPRESSION_FACTOR_768 / (size_t)8U) + LIBCRUX_ML_KEM_MLKEM768_VECTOR_V_COMPRESSION_FACTOR / (size_t)8U) -#define LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768 \ - (LIBCRUX_ML_KEM_MLKEM768_C1_SIZE_768 + LIBCRUX_ML_KEM_MLKEM768_C2_SIZE_768) +#define LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE \ + (LIBCRUX_ML_KEM_MLKEM768_C1_SIZE + LIBCRUX_ML_KEM_MLKEM768_C2_SIZE) -#define LIBCRUX_ML_KEM_MLKEM768_T_AS_NTT_ENCODED_SIZE_768 \ - (LIBCRUX_ML_KEM_MLKEM768_RANK_768 * \ +#define LIBCRUX_ML_KEM_MLKEM768_T_AS_NTT_ENCODED_SIZE \ + (LIBCRUX_ML_KEM_MLKEM768_RANK * \ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) -#define LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE_768 \ - (LIBCRUX_ML_KEM_MLKEM768_T_AS_NTT_ENCODED_SIZE_768 + (size_t)32U) +#define LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE \ + (LIBCRUX_ML_KEM_MLKEM768_T_AS_NTT_ENCODED_SIZE + (size_t)32U) -#define LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_SECRET_KEY_SIZE_768 \ - (LIBCRUX_ML_KEM_MLKEM768_RANK_768 * \ - LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ +#define LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_SECRET_KEY_SIZE \ + (LIBCRUX_ML_KEM_MLKEM768_RANK * \ + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) #define LIBCRUX_ML_KEM_MLKEM768_ETA1 ((size_t)2U) @@ -8155,22 +7018,22 @@ static inline size_t libcrux_ml_kem_vector_portable_rej_sample_0d( #define LIBCRUX_ML_KEM_MLKEM768_IMPLICIT_REJECTION_HASH_INPUT_SIZE \ (LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE + \ - LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768) + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE) -typedef libcrux_ml_kem_types_MlKemPrivateKey_55 +typedef libcrux_ml_kem_types_MlKemPrivateKey_d9 libcrux_ml_kem_mlkem768_MlKem768PrivateKey; -typedef libcrux_ml_kem_types_MlKemPublicKey_15 +typedef libcrux_ml_kem_types_MlKemPublicKey_30 libcrux_ml_kem_mlkem768_MlKem768PublicKey; -#define LIBCRUX_ML_KEM_MLKEM768_RANKED_BYTES_PER_RING_ELEMENT_768 \ - (LIBCRUX_ML_KEM_MLKEM768_RANK_768 * \ +#define LIBCRUX_ML_KEM_MLKEM768_RANKED_BYTES_PER_RING_ELEMENT \ + (LIBCRUX_ML_KEM_MLKEM768_RANK * \ LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT / (size_t)8U) -#define LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768 \ - (LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_SECRET_KEY_SIZE_768 + \ - LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE_768 + \ - LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + \ +#define LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE \ + (LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_SECRET_KEY_SIZE + \ + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE + \ + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + \ LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) /** @@ -8178,51 +7041,65 @@ A monomorphic instance of libcrux_ml_kem.polynomial.PolynomialRingElement with types libcrux_ml_kem_vector_portable_vector_type_PortableVector */ -typedef struct libcrux_ml_kem_polynomial_PolynomialRingElement_f0_s { +typedef struct libcrux_ml_kem_polynomial_PolynomialRingElement_1d_s { libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficients[16U]; -} libcrux_ml_kem_polynomial_PolynomialRingElement_f0; +} libcrux_ml_kem_polynomial_PolynomialRingElement_1d; + +/** +A monomorphic instance of +libcrux_ml_kem.ind_cpa.unpacked.IndCpaPrivateKeyUnpacked with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- $3size_t +*/ +typedef struct libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_a0_s { + libcrux_ml_kem_polynomial_PolynomialRingElement_1d secret_as_ntt[3U]; +} libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_a0; /** This function found in impl -{libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0]} +{libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0, +TraitClause@1]} */ /** -A monomorphic instance of libcrux_ml_kem.polynomial.ZERO_89 +A monomorphic instance of libcrux_ml_kem.polynomial.ZERO_d6 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ -static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_polynomial_ZERO_89_ea(void) { - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 lit; - lit.coefficients[0U] = libcrux_ml_kem_vector_portable_ZERO_0d(); - lit.coefficients[1U] = libcrux_ml_kem_vector_portable_ZERO_0d(); - lit.coefficients[2U] = libcrux_ml_kem_vector_portable_ZERO_0d(); - lit.coefficients[3U] = libcrux_ml_kem_vector_portable_ZERO_0d(); - lit.coefficients[4U] = libcrux_ml_kem_vector_portable_ZERO_0d(); - lit.coefficients[5U] = libcrux_ml_kem_vector_portable_ZERO_0d(); - lit.coefficients[6U] = libcrux_ml_kem_vector_portable_ZERO_0d(); - lit.coefficients[7U] = libcrux_ml_kem_vector_portable_ZERO_0d(); - lit.coefficients[8U] = libcrux_ml_kem_vector_portable_ZERO_0d(); - lit.coefficients[9U] = libcrux_ml_kem_vector_portable_ZERO_0d(); - lit.coefficients[10U] = libcrux_ml_kem_vector_portable_ZERO_0d(); - lit.coefficients[11U] = libcrux_ml_kem_vector_portable_ZERO_0d(); - lit.coefficients[12U] = libcrux_ml_kem_vector_portable_ZERO_0d(); - lit.coefficients[13U] = libcrux_ml_kem_vector_portable_ZERO_0d(); - lit.coefficients[14U] = libcrux_ml_kem_vector_portable_ZERO_0d(); - lit.coefficients[15U] = libcrux_ml_kem_vector_portable_ZERO_0d(); +static inline libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_polynomial_ZERO_d6_ea(void) { + libcrux_ml_kem_polynomial_PolynomialRingElement_1d lit; + libcrux_ml_kem_vector_portable_vector_type_PortableVector + repeat_expression[16U]; + for (size_t i = (size_t)0U; i < (size_t)16U; i++) { + repeat_expression[i] = libcrux_ml_kem_vector_portable_ZERO_b8(); + } + memcpy(lit.coefficients, repeat_expression, + (size_t)16U * + sizeof(libcrux_ml_kem_vector_portable_vector_type_PortableVector)); return lit; } /** -A monomorphic instance of libcrux_ml_kem.ind_cpa.deserialize_secret_key.closure +This function found in impl {core::ops::function::FnMut<(usize), +libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0, +TraitClause@1]> for libcrux_ml_kem::ind_cpa::decrypt::closure[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.decrypt.call_mut_0b with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics - K= 3 +- CIPHERTEXT_SIZE= 1088 +- VECTOR_U_ENCODED_SIZE= 960 +- U_COMPRESSION_FACTOR= 10 +- V_COMPRESSION_FACTOR= 4 */ -static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_ind_cpa_deserialize_secret_key_closure_6b(size_t _) { - return libcrux_ml_kem_polynomial_ZERO_89_ea(); +static inline libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_ind_cpa_decrypt_call_mut_0b_42(void **_, size_t tupled_args) { + return libcrux_ml_kem_polynomial_ZERO_d6_ea(); } /** @@ -8231,18 +7108,19 @@ libcrux_ml_kem.serialize.deserialize_to_uncompressed_ring_element with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ -static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_serialize_deserialize_to_uncompressed_ring_element_af( +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_serialize_deserialize_to_uncompressed_ring_element_ea( Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re = - libcrux_ml_kem_polynomial_ZERO_89_ea(); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d re = + libcrux_ml_kem_polynomial_ZERO_d6_ea(); for (size_t i = (size_t)0U; i < Eurydice_slice_len(serialized, uint8_t) / (size_t)24U; i++) { size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice2( - serialized, i0 * (size_t)24U, i0 * (size_t)24U + (size_t)24U, uint8_t); + Eurydice_slice bytes = + Eurydice_slice_subslice3(serialized, i0 * (size_t)24U, + i0 * (size_t)24U + (size_t)24U, uint8_t *); libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = - libcrux_ml_kem_vector_portable_deserialize_12_0d(bytes); + libcrux_ml_kem_vector_portable_deserialize_12_b8(bytes); re.coefficients[i0] = uu____0; } return re; @@ -8252,59 +7130,47 @@ libcrux_ml_kem_serialize_deserialize_to_uncompressed_ring_element_af( Call [`deserialize_to_uncompressed_ring_element`] for each ring element. */ /** -A monomorphic instance of libcrux_ml_kem.ind_cpa.deserialize_secret_key +A monomorphic instance of libcrux_ml_kem.ind_cpa.deserialize_vector with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics - K= 3 */ -static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_deserialize_secret_key_24( +static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_deserialize_vector_1b( Eurydice_slice secret_key, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 secret_as_ntt[3U]; + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *secret_as_ntt) { for (size_t i = (size_t)0U; i < (size_t)3U; i++) { - secret_as_ntt[i] = libcrux_ml_kem_polynomial_ZERO_89_ea(); - } - for (size_t i = (size_t)0U; - i < Eurydice_slice_len(secret_key, uint8_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { size_t i0 = i; - Eurydice_slice secret_bytes = Eurydice_slice_subslice2( - secret_key, i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - uint8_t); - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 uu____0 = - libcrux_ml_kem_serialize_deserialize_to_uncompressed_ring_element_af( - secret_bytes); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d uu____0 = + libcrux_ml_kem_serialize_deserialize_to_uncompressed_ring_element_ea( + Eurydice_slice_subslice3( + secret_key, + i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + (i0 + (size_t)1U) * + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + uint8_t *)); secret_as_ntt[i0] = uu____0; } - memcpy( - ret, secret_as_ntt, - (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); } /** -A monomorphic instance of -libcrux_ml_kem.ind_cpa.unpacked.IndCpaPrivateKeyUnpacked with types -libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics -- $3size_t +This function found in impl {core::ops::function::FnMut<(usize), +libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0, +TraitClause@1]> for +libcrux_ml_kem::ind_cpa::deserialize_then_decompress_u::closure[TraitClause@0, TraitClause@1]} */ -typedef struct libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_f8_s { - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 secret_as_ntt[3U]; -} libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_f8; - /** A monomorphic instance of -libcrux_ml_kem.ind_cpa.deserialize_then_decompress_u.closure with types +libcrux_ml_kem.ind_cpa.deserialize_then_decompress_u.call_mut_35 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics - K= 3 - CIPHERTEXT_SIZE= 1088 - U_COMPRESSION_FACTOR= 10 */ -static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_ind_cpa_deserialize_then_decompress_u_closure_7c(size_t _) { - return libcrux_ml_kem_polynomial_ZERO_89_ea(); +static inline libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_ind_cpa_deserialize_then_decompress_u_call_mut_35_6c( + void **_, size_t tupled_args) { + return libcrux_ml_kem_polynomial_ZERO_d6_ea(); } /** @@ -8314,35 +7180,38 @@ const generics - COEFFICIENT_BITS= 10 */ static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_6b( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { +libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_ef( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a) { for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { size_t i0 = i; - int32_t decompressed = (int32_t)v.elements[i0] * - (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + int32_t decompressed = + libcrux_secrets_int_as_i32_f5(a.elements[i0]) * + libcrux_secrets_int_as_i32_f5( + libcrux_secrets_int_public_integers_classify_27_39( + LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)10); decompressed = decompressed >> (uint32_t)((int32_t)10 + (int32_t)1); - v.elements[i0] = (int16_t)decompressed; + a.elements[i0] = libcrux_secrets_int_as_i16_36(decompressed); } - return v; + return a; } /** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} */ /** A monomorphic instance of -libcrux_ml_kem.vector.portable.decompress_ciphertext_coefficient_0d with const +libcrux_ml_kem.vector.portable.decompress_ciphertext_coefficient_b8 with const generics - COEFFICIENT_BITS= 10 */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_5a( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { - return libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_6b( - v); +libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_b8_ef( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a) { + return libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_ef( + a); } /** @@ -8351,20 +7220,21 @@ libcrux_ml_kem.serialize.deserialize_then_decompress_10 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ -static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_serialize_deserialize_then_decompress_10_2c( +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_serialize_deserialize_then_decompress_10_ea( Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re = - libcrux_ml_kem_polynomial_ZERO_89_ea(); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d re = + libcrux_ml_kem_polynomial_ZERO_d6_ea(); for (size_t i = (size_t)0U; i < Eurydice_slice_len(serialized, uint8_t) / (size_t)20U; i++) { size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice2( - serialized, i0 * (size_t)20U, i0 * (size_t)20U + (size_t)20U, uint8_t); + Eurydice_slice bytes = + Eurydice_slice_subslice3(serialized, i0 * (size_t)20U, + i0 * (size_t)20U + (size_t)20U, uint8_t *); libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = - libcrux_ml_kem_vector_portable_deserialize_10_0d(bytes); + libcrux_ml_kem_vector_portable_deserialize_10_b8(bytes); libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = - libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_5a( + libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_b8_ef( coefficient); re.coefficients[i0] = uu____0; } @@ -8373,78 +7243,14 @@ libcrux_ml_kem_serialize_deserialize_then_decompress_10_2c( /** A monomorphic instance of -libcrux_ml_kem.vector.portable.compress.decompress_ciphertext_coefficient with -const generics -- COEFFICIENT_BITS= 11 +libcrux_ml_kem.serialize.deserialize_then_decompress_ring_element_u with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- COMPRESSION_FACTOR= 10 */ -static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_6b0( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { - size_t i0 = i; - int32_t decompressed = (int32_t)v.elements[i0] * - (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; - decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)11); - decompressed = decompressed >> (uint32_t)((int32_t)11 + (int32_t)1); - v.elements[i0] = (int16_t)decompressed; - } - return v; -} - -/** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} -*/ -/** -A monomorphic instance of -libcrux_ml_kem.vector.portable.decompress_ciphertext_coefficient_0d with const -generics -- COEFFICIENT_BITS= 11 -*/ -static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_5a0( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { - return libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_6b0( - v); -} - -/** -A monomorphic instance of -libcrux_ml_kem.serialize.deserialize_then_decompress_11 with types -libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics - -*/ -static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_serialize_deserialize_then_decompress_11_8d( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re = - libcrux_ml_kem_polynomial_ZERO_89_ea(); - for (size_t i = (size_t)0U; - i < Eurydice_slice_len(serialized, uint8_t) / (size_t)22U; i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice2( - serialized, i0 * (size_t)22U, i0 * (size_t)22U + (size_t)22U, uint8_t); - libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = - libcrux_ml_kem_vector_portable_deserialize_11_0d(bytes); - libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = - libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_5a0( - coefficient); - re.coefficients[i0] = uu____0; - } - return re; -} - -/** -A monomorphic instance of -libcrux_ml_kem.serialize.deserialize_then_decompress_ring_element_u with types -libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics -- COMPRESSION_FACTOR= 10 -*/ -static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_u_34( +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_u_0a( Eurydice_slice serialized) { - return libcrux_ml_kem_serialize_deserialize_then_decompress_10_2c(serialized); + return libcrux_ml_kem_serialize_deserialize_then_decompress_10_ea(serialized); } typedef struct libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2_s { @@ -8452,19 +7258,6 @@ typedef struct libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2_s { libcrux_ml_kem_vector_portable_vector_type_PortableVector snd; } libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2; -/** -A monomorphic instance of libcrux_ml_kem.vector.traits.montgomery_multiply_fe -with types libcrux_ml_kem_vector_portable_vector_type_PortableVector -with const generics - -*/ -static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_traits_montgomery_multiply_fe_67( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t fer) { - return libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_0d(v, - fer); -} - /** A monomorphic instance of libcrux_ml_kem.ntt.ntt_layer_int_vec_step with types libcrux_ml_kem_vector_portable_vector_type_PortableVector @@ -8473,17 +7266,18 @@ with const generics */ static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2 - libcrux_ml_kem_ntt_ntt_layer_int_vec_step_0c( + libcrux_ml_kem_ntt_ntt_layer_int_vec_step_ea( libcrux_ml_kem_vector_portable_vector_type_PortableVector a, libcrux_ml_kem_vector_portable_vector_type_PortableVector b, int16_t zeta_r) { libcrux_ml_kem_vector_portable_vector_type_PortableVector t = - libcrux_ml_kem_vector_traits_montgomery_multiply_fe_67(b, zeta_r); - b = libcrux_ml_kem_vector_portable_sub_0d(a, &t); - a = libcrux_ml_kem_vector_portable_add_0d(a, &t); - return ( - CLITERAL(libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2){ - .fst = a, .snd = b}); + libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_b8(b, + zeta_r); + b = libcrux_ml_kem_vector_portable_sub_b8(a, &t); + a = libcrux_ml_kem_vector_portable_add_b8(a, &t); + return (KRML_CLITERAL( + libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2){.fst = a, + .snd = b}); } /** @@ -8492,8 +7286,8 @@ with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ -static KRML_MUSTINLINE void libcrux_ml_kem_ntt_ntt_at_layer_4_plus_51( - size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, +static KRML_MUSTINLINE void libcrux_ml_kem_ntt_ntt_at_layer_4_plus_ea( + size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re, size_t layer, size_t _initial_coefficient_bound) { size_t step = (size_t)1U << (uint32_t)layer; for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { @@ -8505,9 +7299,9 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ntt_ntt_at_layer_4_plus_51( for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { size_t j = i; libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2 uu____0 = - libcrux_ml_kem_ntt_ntt_layer_int_vec_step_0c( + libcrux_ml_kem_ntt_ntt_layer_int_vec_step_ea( re->coefficients[j], re->coefficients[j + step_vec], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + libcrux_ml_kem_polynomial_zeta(zeta_i[0U])); libcrux_ml_kem_vector_portable_vector_type_PortableVector x = uu____0.fst; libcrux_ml_kem_vector_portable_vector_type_PortableVector y = uu____0.snd; re->coefficients[j] = x; @@ -8522,16 +7316,16 @@ with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ -static KRML_MUSTINLINE void libcrux_ml_kem_ntt_ntt_at_layer_3_fd( - size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, - size_t _layer, size_t _initial_coefficient_bound) { +static KRML_MUSTINLINE void libcrux_ml_kem_ntt_ntt_at_layer_3_ea( + size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re, + size_t _initial_coefficient_bound) { for (size_t i = (size_t)0U; i < (size_t)16U; i++) { size_t round = i; zeta_i[0U] = zeta_i[0U] + (size_t)1U; libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = - libcrux_ml_kem_vector_portable_ntt_layer_3_step_0d( + libcrux_ml_kem_vector_portable_ntt_layer_3_step_b8( re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + libcrux_ml_kem_polynomial_zeta(zeta_i[0U])); re->coefficients[round] = uu____0; } } @@ -8542,18 +7336,16 @@ with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ -static KRML_MUSTINLINE void libcrux_ml_kem_ntt_ntt_at_layer_2_ad( - size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, - size_t _layer, size_t _initial_coefficient_bound) { +static KRML_MUSTINLINE void libcrux_ml_kem_ntt_ntt_at_layer_2_ea( + size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re, + size_t _initial_coefficient_bound) { for (size_t i = (size_t)0U; i < (size_t)16U; i++) { size_t round = i; zeta_i[0U] = zeta_i[0U] + (size_t)1U; re->coefficients[round] = - libcrux_ml_kem_vector_portable_ntt_layer_2_step_0d( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + - (size_t)1U]); + libcrux_ml_kem_vector_portable_ntt_layer_2_step_b8( + re->coefficients[round], libcrux_ml_kem_polynomial_zeta(zeta_i[0U]), + libcrux_ml_kem_polynomial_zeta(zeta_i[0U] + (size_t)1U)); zeta_i[0U] = zeta_i[0U] + (size_t)1U; } } @@ -8564,69 +7356,77 @@ with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ -static KRML_MUSTINLINE void libcrux_ml_kem_ntt_ntt_at_layer_1_a2( - size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, - size_t _layer, size_t _initial_coefficient_bound) { +static KRML_MUSTINLINE void libcrux_ml_kem_ntt_ntt_at_layer_1_ea( + size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re, + size_t _initial_coefficient_bound) { for (size_t i = (size_t)0U; i < (size_t)16U; i++) { size_t round = i; zeta_i[0U] = zeta_i[0U] + (size_t)1U; re->coefficients[round] = - libcrux_ml_kem_vector_portable_ntt_layer_1_step_0d( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + - (size_t)1U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + - (size_t)2U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + - (size_t)3U]); + libcrux_ml_kem_vector_portable_ntt_layer_1_step_b8( + re->coefficients[round], libcrux_ml_kem_polynomial_zeta(zeta_i[0U]), + libcrux_ml_kem_polynomial_zeta(zeta_i[0U] + (size_t)1U), + libcrux_ml_kem_polynomial_zeta(zeta_i[0U] + (size_t)2U), + libcrux_ml_kem_polynomial_zeta(zeta_i[0U] + (size_t)3U)); zeta_i[0U] = zeta_i[0U] + (size_t)3U; } } /** -This function found in impl -{libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0]} -*/ -/** -A monomorphic instance of libcrux_ml_kem.polynomial.poly_barrett_reduce_89 +A monomorphic instance of libcrux_ml_kem.polynomial.poly_barrett_reduce with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ -static KRML_MUSTINLINE void libcrux_ml_kem_polynomial_poly_barrett_reduce_89_8b( - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *self) { +static KRML_MUSTINLINE void libcrux_ml_kem_polynomial_poly_barrett_reduce_ea( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *myself) { for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t i0 = i; libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = - libcrux_ml_kem_vector_portable_barrett_reduce_0d( - self->coefficients[i0]); - self->coefficients[i0] = uu____0; + libcrux_ml_kem_vector_portable_barrett_reduce_b8( + myself->coefficients[i0]); + myself->coefficients[i0] = uu____0; } } +/** +This function found in impl +{libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0, +TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_ml_kem.polynomial.poly_barrett_reduce_d6 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_polynomial_poly_barrett_reduce_d6_ea( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *self) { + libcrux_ml_kem_polynomial_poly_barrett_reduce_ea(self); +} + /** A monomorphic instance of libcrux_ml_kem.ntt.ntt_vector_u with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics - VECTOR_U_COMPRESSION_FACTOR= 10 */ -static KRML_MUSTINLINE void libcrux_ml_kem_ntt_ntt_vector_u_9f( - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re) { +static KRML_MUSTINLINE void libcrux_ml_kem_ntt_ntt_vector_u_0a( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re) { size_t zeta_i = (size_t)0U; - libcrux_ml_kem_ntt_ntt_at_layer_4_plus_51(&zeta_i, re, (size_t)7U, - (size_t)3328U); - libcrux_ml_kem_ntt_ntt_at_layer_4_plus_51(&zeta_i, re, (size_t)6U, - (size_t)3328U); - libcrux_ml_kem_ntt_ntt_at_layer_4_plus_51(&zeta_i, re, (size_t)5U, + libcrux_ml_kem_ntt_ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)7U, (size_t)3328U); - libcrux_ml_kem_ntt_ntt_at_layer_4_plus_51(&zeta_i, re, (size_t)4U, - (size_t)3328U); - libcrux_ml_kem_ntt_ntt_at_layer_3_fd(&zeta_i, re, (size_t)3U, (size_t)3328U); - libcrux_ml_kem_ntt_ntt_at_layer_2_ad(&zeta_i, re, (size_t)2U, (size_t)3328U); - libcrux_ml_kem_ntt_ntt_at_layer_1_a2(&zeta_i, re, (size_t)1U, (size_t)3328U); - libcrux_ml_kem_polynomial_poly_barrett_reduce_89_8b(re); + libcrux_ml_kem_ntt_ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)6U, + (size_t)2U * (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)5U, + (size_t)3U * (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)4U, + (size_t)4U * (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_3_ea(&zeta_i, re, (size_t)5U * (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_2_ea(&zeta_i, re, (size_t)6U * (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_1_ea(&zeta_i, re, (size_t)7U * (size_t)3328U); + libcrux_ml_kem_polynomial_poly_barrett_reduce_d6_ea(re); } /** @@ -8642,12 +7442,16 @@ with const generics - U_COMPRESSION_FACTOR= 10 */ static KRML_MUSTINLINE void -libcrux_ml_kem_ind_cpa_deserialize_then_decompress_u_f4( +libcrux_ml_kem_ind_cpa_deserialize_then_decompress_u_6c( uint8_t *ciphertext, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 u_as_ntt[3U]; + libcrux_ml_kem_polynomial_PolynomialRingElement_1d ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement_1d u_as_ntt[3U]; for (size_t i = (size_t)0U; i < (size_t)3U; i++) { - u_as_ntt[i] = libcrux_ml_kem_polynomial_ZERO_89_ea(); + /* original Rust expression is not an lvalue in C */ + void *lvalue = (void *)0U; + u_as_ntt[i] = + libcrux_ml_kem_ind_cpa_deserialize_then_decompress_u_call_mut_35_6c( + &lvalue, i); } for (size_t i = (size_t)0U; i < Eurydice_slice_len( @@ -8657,7 +7461,7 @@ libcrux_ml_kem_ind_cpa_deserialize_then_decompress_u_f4( (size_t)10U / (size_t)8U); i++) { size_t i0 = i; - Eurydice_slice u_bytes = Eurydice_array_to_subslice2( + Eurydice_slice u_bytes = Eurydice_array_to_subslice3( ciphertext, i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U), @@ -8665,15 +7469,15 @@ libcrux_ml_kem_ind_cpa_deserialize_then_decompress_u_f4( (size_t)10U / (size_t)8U) + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)10U / (size_t)8U, - uint8_t); + uint8_t *); u_as_ntt[i0] = - libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_u_34( + libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_u_0a( u_bytes); - libcrux_ml_kem_ntt_ntt_vector_u_9f(&u_as_ntt[i0]); + libcrux_ml_kem_ntt_ntt_vector_u_0a(&u_as_ntt[i0]); } memcpy( ret, u_as_ntt, - (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); } /** @@ -8683,35 +7487,38 @@ const generics - COEFFICIENT_BITS= 4 */ static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_6b1( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { +libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_d1( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a) { for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { size_t i0 = i; - int32_t decompressed = (int32_t)v.elements[i0] * - (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + int32_t decompressed = + libcrux_secrets_int_as_i32_f5(a.elements[i0]) * + libcrux_secrets_int_as_i32_f5( + libcrux_secrets_int_public_integers_classify_27_39( + LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)4); decompressed = decompressed >> (uint32_t)((int32_t)4 + (int32_t)1); - v.elements[i0] = (int16_t)decompressed; + a.elements[i0] = libcrux_secrets_int_as_i16_36(decompressed); } - return v; + return a; } /** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} */ /** A monomorphic instance of -libcrux_ml_kem.vector.portable.decompress_ciphertext_coefficient_0d with const +libcrux_ml_kem.vector.portable.decompress_ciphertext_coefficient_b8 with const generics - COEFFICIENT_BITS= 4 */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_5a1( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { - return libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_6b1( - v); +libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_b8_d1( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a) { + return libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_d1( + a); } /** @@ -8720,20 +7527,20 @@ with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ -static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_serialize_deserialize_then_decompress_4_41( +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_serialize_deserialize_then_decompress_4_ea( Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re = - libcrux_ml_kem_polynomial_ZERO_89_ea(); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d re = + libcrux_ml_kem_polynomial_ZERO_d6_ea(); for (size_t i = (size_t)0U; i < Eurydice_slice_len(serialized, uint8_t) / (size_t)8U; i++) { size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice2( - serialized, i0 * (size_t)8U, i0 * (size_t)8U + (size_t)8U, uint8_t); + Eurydice_slice bytes = Eurydice_slice_subslice3( + serialized, i0 * (size_t)8U, i0 * (size_t)8U + (size_t)8U, uint8_t *); libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = - libcrux_ml_kem_vector_portable_deserialize_4_0d(bytes); + libcrux_ml_kem_vector_portable_deserialize_4_b8(bytes); libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = - libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_5a1( + libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_b8_d1( coefficient); re.coefficients[i0] = uu____0; } @@ -8742,78 +7549,35 @@ libcrux_ml_kem_serialize_deserialize_then_decompress_4_41( /** A monomorphic instance of -libcrux_ml_kem.vector.portable.compress.decompress_ciphertext_coefficient with -const generics -- COEFFICIENT_BITS= 5 -*/ -static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_6b2( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { - size_t i0 = i; - int32_t decompressed = (int32_t)v.elements[i0] * - (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; - decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)5); - decompressed = decompressed >> (uint32_t)((int32_t)5 + (int32_t)1); - v.elements[i0] = (int16_t)decompressed; - } - return v; -} - -/** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} -*/ -/** -A monomorphic instance of -libcrux_ml_kem.vector.portable.decompress_ciphertext_coefficient_0d with const -generics -- COEFFICIENT_BITS= 5 +libcrux_ml_kem.serialize.deserialize_then_decompress_ring_element_v with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- K= 3 +- COMPRESSION_FACTOR= 4 */ -static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_5a2( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { - return libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_6b2( - v); +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v_89( + Eurydice_slice serialized) { + return libcrux_ml_kem_serialize_deserialize_then_decompress_4_ea(serialized); } /** -A monomorphic instance of libcrux_ml_kem.serialize.deserialize_then_decompress_5 +A monomorphic instance of libcrux_ml_kem.polynomial.ZERO with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ -static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_serialize_deserialize_then_decompress_5_4e( - Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re = - libcrux_ml_kem_polynomial_ZERO_89_ea(); - for (size_t i = (size_t)0U; - i < Eurydice_slice_len(serialized, uint8_t) / (size_t)10U; i++) { - size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice2( - serialized, i0 * (size_t)10U, i0 * (size_t)10U + (size_t)10U, uint8_t); - re.coefficients[i0] = - libcrux_ml_kem_vector_portable_deserialize_5_0d(bytes); - libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____1 = - libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_5a2( - re.coefficients[i0]); - re.coefficients[i0] = uu____1; +static inline libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_polynomial_ZERO_ea(void) { + libcrux_ml_kem_polynomial_PolynomialRingElement_1d lit; + libcrux_ml_kem_vector_portable_vector_type_PortableVector + repeat_expression[16U]; + for (size_t i = (size_t)0U; i < (size_t)16U; i++) { + repeat_expression[i] = libcrux_ml_kem_vector_portable_ZERO_b8(); } - return re; -} - -/** -A monomorphic instance of -libcrux_ml_kem.serialize.deserialize_then_decompress_ring_element_v with types -libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics -- COMPRESSION_FACTOR= 4 -*/ -static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v_56( - Eurydice_slice serialized) { - return libcrux_ml_kem_serialize_deserialize_then_decompress_4_41(serialized); + memcpy(lit.coefficients, repeat_expression, + (size_t)16U * + sizeof(libcrux_ml_kem_vector_portable_vector_type_PortableVector)); + return lit; } /** @@ -8844,97 +7608,115 @@ libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v_56( . */ /** -This function found in impl -{libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0]} -*/ -/** -A monomorphic instance of libcrux_ml_kem.polynomial.ntt_multiply_89 +A monomorphic instance of libcrux_ml_kem.polynomial.ntt_multiply with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ -static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_polynomial_ntt_multiply_89_2a( - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *self, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *rhs) { - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 out = - libcrux_ml_kem_polynomial_ZERO_89_ea(); +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_polynomial_ntt_multiply_ea( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *myself, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *rhs) { + libcrux_ml_kem_polynomial_PolynomialRingElement_1d out = + libcrux_ml_kem_polynomial_ZERO_ea(); for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t i0 = i; libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = - libcrux_ml_kem_vector_portable_ntt_multiply_0d( - &self->coefficients[i0], &rhs->coefficients[i0], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + - (size_t)4U * i0], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + - (size_t)4U * i0 + - (size_t)1U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + - (size_t)4U * i0 + - (size_t)2U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + - (size_t)4U * i0 + - (size_t)3U]); + libcrux_ml_kem_vector_portable_ntt_multiply_b8( + &myself->coefficients[i0], &rhs->coefficients[i0], + libcrux_ml_kem_polynomial_zeta((size_t)64U + (size_t)4U * i0), + libcrux_ml_kem_polynomial_zeta((size_t)64U + (size_t)4U * i0 + + (size_t)1U), + libcrux_ml_kem_polynomial_zeta((size_t)64U + (size_t)4U * i0 + + (size_t)2U), + libcrux_ml_kem_polynomial_zeta((size_t)64U + (size_t)4U * i0 + + (size_t)3U)); out.coefficients[i0] = uu____0; } return out; } /** - Given two polynomial ring elements `lhs` and `rhs`, compute the pointwise - sum of their constituent coefficients. +This function found in impl +{libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0, +TraitClause@1]} */ /** -This function found in impl -{libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0]} +A monomorphic instance of libcrux_ml_kem.polynomial.ntt_multiply_d6 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_polynomial_ntt_multiply_d6_ea( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *self, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *rhs) { + return libcrux_ml_kem_polynomial_ntt_multiply_ea(self, rhs); +} + +/** + Given two polynomial ring elements `lhs` and `rhs`, compute the pointwise + sum of their constituent coefficients. */ /** -A monomorphic instance of libcrux_ml_kem.polynomial.add_to_ring_element_89 +A monomorphic instance of libcrux_ml_kem.polynomial.add_to_ring_element with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics - K= 3 */ -static KRML_MUSTINLINE void libcrux_ml_kem_polynomial_add_to_ring_element_89_84( - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *self, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *rhs) { +static KRML_MUSTINLINE void libcrux_ml_kem_polynomial_add_to_ring_element_1b( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *myself, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *rhs) { for (size_t i = (size_t)0U; i < Eurydice_slice_len( Eurydice_array_to_slice( - (size_t)16U, self->coefficients, + (size_t)16U, myself->coefficients, libcrux_ml_kem_vector_portable_vector_type_PortableVector), libcrux_ml_kem_vector_portable_vector_type_PortableVector); i++) { size_t i0 = i; libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = - libcrux_ml_kem_vector_portable_add_0d(self->coefficients[i0], + libcrux_ml_kem_vector_portable_add_b8(myself->coefficients[i0], &rhs->coefficients[i0]); - self->coefficients[i0] = uu____0; + myself->coefficients[i0] = uu____0; } } +/** +This function found in impl +{libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0, +TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_ml_kem.polynomial.add_to_ring_element_d6 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_polynomial_add_to_ring_element_d6_1b( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *self, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *rhs) { + libcrux_ml_kem_polynomial_add_to_ring_element_1b(self, rhs); +} + /** A monomorphic instance of libcrux_ml_kem.invert_ntt.invert_ntt_at_layer_1 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ -static KRML_MUSTINLINE void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_1_83( - size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, - size_t _layer) { +static KRML_MUSTINLINE void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_1_ea( + size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re) { for (size_t i = (size_t)0U; i < (size_t)16U; i++) { size_t round = i; zeta_i[0U] = zeta_i[0U] - (size_t)1U; re->coefficients[round] = - libcrux_ml_kem_vector_portable_inv_ntt_layer_1_step_0d( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - - (size_t)1U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - - (size_t)2U], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - - (size_t)3U]); + libcrux_ml_kem_vector_portable_inv_ntt_layer_1_step_b8( + re->coefficients[round], libcrux_ml_kem_polynomial_zeta(zeta_i[0U]), + libcrux_ml_kem_polynomial_zeta(zeta_i[0U] - (size_t)1U), + libcrux_ml_kem_polynomial_zeta(zeta_i[0U] - (size_t)2U), + libcrux_ml_kem_polynomial_zeta(zeta_i[0U] - (size_t)3U)); zeta_i[0U] = zeta_i[0U] - (size_t)3U; } } @@ -8945,18 +7727,15 @@ with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ -static KRML_MUSTINLINE void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_2_c3( - size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, - size_t _layer) { +static KRML_MUSTINLINE void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_2_ea( + size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re) { for (size_t i = (size_t)0U; i < (size_t)16U; i++) { size_t round = i; zeta_i[0U] = zeta_i[0U] - (size_t)1U; re->coefficients[round] = - libcrux_ml_kem_vector_portable_inv_ntt_layer_2_step_0d( - re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - - (size_t)1U]); + libcrux_ml_kem_vector_portable_inv_ntt_layer_2_step_b8( + re->coefficients[round], libcrux_ml_kem_polynomial_zeta(zeta_i[0U]), + libcrux_ml_kem_polynomial_zeta(zeta_i[0U] - (size_t)1U)); zeta_i[0U] = zeta_i[0U] - (size_t)1U; } } @@ -8967,16 +7746,15 @@ with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ -static KRML_MUSTINLINE void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_3_68( - size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, - size_t _layer) { +static KRML_MUSTINLINE void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_3_ea( + size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re) { for (size_t i = (size_t)0U; i < (size_t)16U; i++) { size_t round = i; zeta_i[0U] = zeta_i[0U] - (size_t)1U; libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = - libcrux_ml_kem_vector_portable_inv_ntt_layer_3_step_0d( + libcrux_ml_kem_vector_portable_inv_ntt_layer_3_step_b8( re->coefficients[round], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + libcrux_ml_kem_polynomial_zeta(zeta_i[0U])); re->coefficients[round] = uu____0; } } @@ -8989,18 +7767,19 @@ libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2 - libcrux_ml_kem_invert_ntt_inv_ntt_layer_int_vec_step_reduce_65( + libcrux_ml_kem_invert_ntt_inv_ntt_layer_int_vec_step_reduce_ea( libcrux_ml_kem_vector_portable_vector_type_PortableVector a, libcrux_ml_kem_vector_portable_vector_type_PortableVector b, int16_t zeta_r) { libcrux_ml_kem_vector_portable_vector_type_PortableVector a_minus_b = - libcrux_ml_kem_vector_portable_sub_0d(b, &a); - a = libcrux_ml_kem_vector_portable_barrett_reduce_0d( - libcrux_ml_kem_vector_portable_add_0d(a, &b)); - b = libcrux_ml_kem_vector_traits_montgomery_multiply_fe_67(a_minus_b, zeta_r); - return ( - CLITERAL(libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2){ - .fst = a, .snd = b}); + libcrux_ml_kem_vector_portable_sub_b8(b, &a); + a = libcrux_ml_kem_vector_portable_barrett_reduce_b8( + libcrux_ml_kem_vector_portable_add_b8(a, &b)); + b = libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_b8( + a_minus_b, zeta_r); + return (KRML_CLITERAL( + libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2){.fst = a, + .snd = b}); } /** @@ -9010,8 +7789,8 @@ with const generics */ static KRML_MUSTINLINE void -libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus_6e( - size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, +libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus_ea( + size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re, size_t layer) { size_t step = (size_t)1U << (uint32_t)layer; for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { @@ -9025,9 +7804,9 @@ libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus_6e( for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { size_t j = i; libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2 uu____0 = - libcrux_ml_kem_invert_ntt_inv_ntt_layer_int_vec_step_reduce_65( + libcrux_ml_kem_invert_ntt_inv_ntt_layer_int_vec_step_reduce_ea( re->coefficients[j], re->coefficients[j + step_vec], - libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + libcrux_ml_kem_polynomial_zeta(zeta_i[0U])); libcrux_ml_kem_vector_portable_vector_type_PortableVector x = uu____0.fst; libcrux_ml_kem_vector_portable_vector_type_PortableVector y = uu____0.snd; re->coefficients[j] = x; @@ -9042,54 +7821,69 @@ with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics - K= 3 */ -static KRML_MUSTINLINE void libcrux_ml_kem_invert_ntt_invert_ntt_montgomery_f6( - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re) { +static KRML_MUSTINLINE void libcrux_ml_kem_invert_ntt_invert_ntt_montgomery_1b( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re) { size_t zeta_i = LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_1_83(&zeta_i, re, (size_t)1U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_2_c3(&zeta_i, re, (size_t)2U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_3_68(&zeta_i, re, (size_t)3U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus_6e(&zeta_i, re, + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_1_ea(&zeta_i, re); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_2_ea(&zeta_i, re); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_3_ea(&zeta_i, re); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)4U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus_6e(&zeta_i, re, + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)5U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus_6e(&zeta_i, re, + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)6U); - libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus_6e(&zeta_i, re, + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)7U); - libcrux_ml_kem_polynomial_poly_barrett_reduce_89_8b(re); + libcrux_ml_kem_polynomial_poly_barrett_reduce_d6_ea(re); } /** -This function found in impl -{libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0]} -*/ -/** -A monomorphic instance of libcrux_ml_kem.polynomial.subtract_reduce_89 +A monomorphic instance of libcrux_ml_kem.polynomial.subtract_reduce with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ -static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_polynomial_subtract_reduce_89_d4( - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *self, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 b) { +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_polynomial_subtract_reduce_ea( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *myself, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d b) { for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t i0 = i; libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient_normal_form = - libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_0d( + libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_b8( b.coefficients[i0], (int16_t)1441); - libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = - libcrux_ml_kem_vector_portable_barrett_reduce_0d( - libcrux_ml_kem_vector_portable_sub_0d(self->coefficients[i0], - &coefficient_normal_form)); - b.coefficients[i0] = uu____0; + libcrux_ml_kem_vector_portable_vector_type_PortableVector diff = + libcrux_ml_kem_vector_portable_sub_b8(myself->coefficients[i0], + &coefficient_normal_form); + libcrux_ml_kem_vector_portable_vector_type_PortableVector red = + libcrux_ml_kem_vector_portable_barrett_reduce_b8(diff); + b.coefficients[i0] = red; } return b; } +/** +This function found in impl +{libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0, +TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_ml_kem.polynomial.subtract_reduce_d6 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_polynomial_subtract_reduce_d6_ea( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *self, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d b) { + return libcrux_ml_kem_polynomial_subtract_reduce_ea(self, b); +} + /** The following functions compute various expressions involving vectors and matrices. The computation of these expressions has been @@ -9102,71 +7896,34 @@ with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics - K= 3 */ -static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_matrix_compute_message_b3( - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *v, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *secret_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *u_as_ntt) { - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 result = - libcrux_ml_kem_polynomial_ZERO_89_ea(); +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_matrix_compute_message_1b( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *v, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *secret_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *u_as_ntt) { + libcrux_ml_kem_polynomial_PolynomialRingElement_1d result = + libcrux_ml_kem_polynomial_ZERO_d6_ea(); for (size_t i = (size_t)0U; i < (size_t)3U; i++) { size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 product = - libcrux_ml_kem_polynomial_ntt_multiply_89_2a(&secret_as_ntt[i0], + libcrux_ml_kem_polynomial_PolynomialRingElement_1d product = + libcrux_ml_kem_polynomial_ntt_multiply_d6_ea(&secret_as_ntt[i0], &u_as_ntt[i0]); - libcrux_ml_kem_polynomial_add_to_ring_element_89_84(&result, &product); - } - libcrux_ml_kem_invert_ntt_invert_ntt_montgomery_f6(&result); - result = libcrux_ml_kem_polynomial_subtract_reduce_89_d4(v, result); - return result; -} - -/** -A monomorphic instance of libcrux_ml_kem.vector.portable.arithmetic.shift_right -with const generics -- SHIFT_BY= 15 -*/ -static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_arithmetic_shift_right_94( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { - size_t i0 = i; - v.elements[i0] = v.elements[i0] >> (uint32_t)(int32_t)15; + libcrux_ml_kem_polynomial_add_to_ring_element_d6_1b(&result, &product); } - return v; + libcrux_ml_kem_invert_ntt_invert_ntt_montgomery_1b(&result); + return libcrux_ml_kem_polynomial_subtract_reduce_d6_ea(v, result); } /** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} -*/ -/** -A monomorphic instance of libcrux_ml_kem.vector.portable.shift_right_0d +A monomorphic instance of libcrux_ml_kem.serialize.to_unsigned_field_modulus +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics -- SHIFT_BY= 15 -*/ -static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_shift_right_0d_19( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { - return libcrux_ml_kem_vector_portable_arithmetic_shift_right_94(v); -} - -/** -A monomorphic instance of -libcrux_ml_kem.vector.traits.to_unsigned_representative with types -libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ -static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_traits_to_unsigned_representative_db( +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_serialize_to_unsigned_field_modulus_ea( libcrux_ml_kem_vector_portable_vector_type_PortableVector a) { - libcrux_ml_kem_vector_portable_vector_type_PortableVector t = - libcrux_ml_kem_vector_portable_shift_right_0d_19(a); - libcrux_ml_kem_vector_portable_vector_type_PortableVector fm = - libcrux_ml_kem_vector_portable_bitwise_and_with_constant_0d( - t, LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); - return libcrux_ml_kem_vector_portable_add_0d(a, &fm); + return libcrux_ml_kem_vector_portable_to_unsigned_representative_b8(a); } /** @@ -9176,24 +7933,24 @@ libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ static KRML_MUSTINLINE void -libcrux_ml_kem_serialize_compress_then_serialize_message_aa( - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re, uint8_t ret[32U]) { +libcrux_ml_kem_serialize_compress_then_serialize_message_ea( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d re, uint8_t ret[32U]) { uint8_t serialized[32U] = {0U}; for (size_t i = (size_t)0U; i < (size_t)16U; i++) { size_t i0 = i; libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = - libcrux_ml_kem_vector_traits_to_unsigned_representative_db( + libcrux_ml_kem_serialize_to_unsigned_field_modulus_ea( re.coefficients[i0]); libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient_compressed = - libcrux_ml_kem_vector_portable_compress_1_0d(coefficient); + libcrux_ml_kem_vector_portable_compress_1_b8(coefficient); uint8_t bytes[2U]; - libcrux_ml_kem_vector_portable_serialize_1_0d(coefficient_compressed, + libcrux_ml_kem_vector_portable_serialize_1_b8(coefficient_compressed, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice2( - serialized, (size_t)2U * i0, (size_t)2U * i0 + (size_t)2U, uint8_t); Eurydice_slice_copy( - uu____0, Eurydice_array_to_slice((size_t)2U, bytes, uint8_t), uint8_t); + Eurydice_array_to_subslice3(serialized, (size_t)2U * i0, + (size_t)2U * i0 + (size_t)2U, uint8_t *), + Eurydice_array_to_slice((size_t)2U, bytes, uint8_t), uint8_t); } memcpy(ret, serialized, (size_t)32U * sizeof(uint8_t)); } @@ -9232,20 +7989,21 @@ with const generics - U_COMPRESSION_FACTOR= 10 - V_COMPRESSION_FACTOR= 4 */ -static inline void libcrux_ml_kem_ind_cpa_decrypt_unpacked_6d( - libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_f8 *secret_key, +static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_decrypt_unpacked_42( + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_a0 *secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 u_as_ntt[3U]; - libcrux_ml_kem_ind_cpa_deserialize_then_decompress_u_f4(ciphertext, u_as_ntt); - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 v = - libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v_56( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d u_as_ntt[3U]; + libcrux_ml_kem_ind_cpa_deserialize_then_decompress_u_6c(ciphertext, u_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d v = + libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v_89( Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, - (size_t)960U, uint8_t, size_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 message = - libcrux_ml_kem_matrix_compute_message_b3(&v, secret_key->secret_as_ntt, + (size_t)960U, uint8_t, size_t, + uint8_t[])); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d message = + libcrux_ml_kem_matrix_compute_message_1b(&v, secret_key->secret_as_ntt, u_as_ntt); uint8_t ret0[32U]; - libcrux_ml_kem_serialize_compress_then_serialize_message_aa(message, ret0); + libcrux_ml_kem_serialize_compress_then_serialize_message_ea(message, ret0); memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } @@ -9259,37 +8017,37 @@ with const generics - U_COMPRESSION_FACTOR= 10 - V_COMPRESSION_FACTOR= 4 */ -static inline void libcrux_ml_kem_ind_cpa_decrypt_43(Eurydice_slice secret_key, - uint8_t *ciphertext, - uint8_t ret[32U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 secret_as_ntt[3U]; - libcrux_ml_kem_ind_cpa_deserialize_secret_key_24(secret_key, secret_as_ntt); - /* Passing arrays by value in Rust generates a copy in C */ - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 copy_of_secret_as_ntt[3U]; - memcpy( - copy_of_secret_as_ntt, secret_as_ntt, - (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); - libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_f8 +static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_decrypt_42( + Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_a0 secret_key_unpacked; + libcrux_ml_kem_polynomial_PolynomialRingElement_1d ret0[3U]; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + /* original Rust expression is not an lvalue in C */ + void *lvalue = (void *)0U; + ret0[i] = libcrux_ml_kem_ind_cpa_decrypt_call_mut_0b_42(&lvalue, i); + } memcpy( - secret_key_unpacked.secret_as_ntt, copy_of_secret_as_ntt, - (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); - uint8_t ret0[32U]; - libcrux_ml_kem_ind_cpa_decrypt_unpacked_6d(&secret_key_unpacked, ciphertext, - ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); + secret_key_unpacked.secret_as_ntt, ret0, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); + libcrux_ml_kem_ind_cpa_deserialize_vector_1b( + secret_key, secret_key_unpacked.secret_as_ntt); + uint8_t ret1[32U]; + libcrux_ml_kem_ind_cpa_decrypt_unpacked_42(&secret_key_unpacked, ciphertext, + ret1); + memcpy(ret, ret1, (size_t)32U * sizeof(uint8_t)); } /** -This function found in impl {(libcrux_ml_kem::hash_functions::Hash for -libcrux_ml_kem::hash_functions::portable::PortableHash)} +This function found in impl {libcrux_ml_kem::hash_functions::Hash for +libcrux_ml_kem::hash_functions::portable::PortableHash} */ /** -A monomorphic instance of libcrux_ml_kem.hash_functions.portable.G_f1 +A monomorphic instance of libcrux_ml_kem.hash_functions.portable.G_4a with const generics - K= 3 */ -static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_G_f1_e4( +static inline void libcrux_ml_kem_hash_functions_portable_G_4a_e0( Eurydice_slice input, uint8_t ret[64U]) { libcrux_ml_kem_hash_functions_portable_G(input, ret); } @@ -9299,7 +8057,7 @@ A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRF with const generics - LEN= 32 */ -static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_PRF_2b( +static inline void libcrux_ml_kem_hash_functions_portable_PRF_9e( Eurydice_slice input, uint8_t ret[32U]) { uint8_t digest[32U] = {0U}; libcrux_sha3_portable_shake256( @@ -9308,31 +8066,69 @@ static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_PRF_2b( } /** -This function found in impl {(libcrux_ml_kem::hash_functions::Hash for -libcrux_ml_kem::hash_functions::portable::PortableHash)} +This function found in impl {libcrux_ml_kem::hash_functions::Hash for +libcrux_ml_kem::hash_functions::portable::PortableHash} */ /** -A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRF_f1 +A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRF_4a with const generics - K= 3 - LEN= 32 */ -static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_PRF_f1_ee( +static inline void libcrux_ml_kem_hash_functions_portable_PRF_4a_41( Eurydice_slice input, uint8_t ret[32U]) { - libcrux_ml_kem_hash_functions_portable_PRF_2b(input, ret); + libcrux_ml_kem_hash_functions_portable_PRF_9e(input, ret); } /** A monomorphic instance of -libcrux_ml_kem.serialize.deserialize_ring_elements_reduced.closure with types +libcrux_ml_kem.ind_cpa.unpacked.IndCpaPublicKeyUnpacked with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics -- PUBLIC_KEY_SIZE= 1152 +- $3size_t +*/ +typedef struct libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_a0_s { + libcrux_ml_kem_polynomial_PolynomialRingElement_1d t_as_ntt[3U]; + uint8_t seed_for_A[32U]; + libcrux_ml_kem_polynomial_PolynomialRingElement_1d A[3U][3U]; +} libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_a0; + +/** +This function found in impl {core::default::Default for +libcrux_ml_kem::ind_cpa::unpacked::IndCpaPublicKeyUnpacked[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.unpacked.default_8b +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics - K= 3 */ -static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_closure_cd( - size_t _i) { - return libcrux_ml_kem_polynomial_ZERO_89_ea(); +static inline libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_a0 +libcrux_ml_kem_ind_cpa_unpacked_default_8b_1b(void) { + libcrux_ml_kem_polynomial_PolynomialRingElement_1d uu____0[3U]; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + uu____0[i] = libcrux_ml_kem_polynomial_ZERO_d6_ea(); + } + uint8_t uu____1[32U] = {0U}; + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_a0 lit; + memcpy( + lit.t_as_ntt, uu____0, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); + memcpy(lit.seed_for_A, uu____1, (size_t)32U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d repeat_expression0[3U][3U]; + for (size_t i0 = (size_t)0U; i0 < (size_t)3U; i0++) { + libcrux_ml_kem_polynomial_PolynomialRingElement_1d repeat_expression[3U]; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + repeat_expression[i] = libcrux_ml_kem_polynomial_ZERO_d6_ea(); + } + memcpy(repeat_expression0[i0], repeat_expression, + (size_t)3U * + sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); + } + memcpy(lit.A, repeat_expression0, + (size_t)3U * + sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d[3U])); + return lit; } /** @@ -9347,90 +8143,54 @@ libcrux_ml_kem.serialize.deserialize_to_reduced_ring_element with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ -static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element_4c( +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element_ea( Eurydice_slice serialized) { - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re = - libcrux_ml_kem_polynomial_ZERO_89_ea(); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d re = + libcrux_ml_kem_polynomial_ZERO_d6_ea(); for (size_t i = (size_t)0U; i < Eurydice_slice_len(serialized, uint8_t) / (size_t)24U; i++) { size_t i0 = i; - Eurydice_slice bytes = Eurydice_slice_subslice2( - serialized, i0 * (size_t)24U, i0 * (size_t)24U + (size_t)24U, uint8_t); + Eurydice_slice bytes = + Eurydice_slice_subslice3(serialized, i0 * (size_t)24U, + i0 * (size_t)24U + (size_t)24U, uint8_t *); libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = - libcrux_ml_kem_vector_portable_deserialize_12_0d(bytes); + libcrux_ml_kem_vector_portable_deserialize_12_b8(bytes); libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = - libcrux_ml_kem_vector_portable_cond_subtract_3329_0d(coefficient); + libcrux_ml_kem_vector_portable_cond_subtract_3329_b8(coefficient); re.coefficients[i0] = uu____0; } return re; } /** - This function deserializes ring elements and reduces the result by the field - modulus. - - This function MUST NOT be used on secret inputs. + See [deserialize_ring_elements_reduced_out]. */ /** A monomorphic instance of libcrux_ml_kem.serialize.deserialize_ring_elements_reduced with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics -- PUBLIC_KEY_SIZE= 1152 - K= 3 */ static KRML_MUSTINLINE void -libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_33( +libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_1b( Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 deserialized_pk[3U]; - for (size_t i = (size_t)0U; i < (size_t)3U; i++) { - deserialized_pk[i] = libcrux_ml_kem_polynomial_ZERO_89_ea(); - } + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *deserialized_pk) { for (size_t i = (size_t)0U; i < Eurydice_slice_len(public_key, uint8_t) / LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; i++) { size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice2( + Eurydice_slice ring_element = Eurydice_slice_subslice3( public_key, i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - uint8_t); - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 uu____0 = - libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element_4c( + uint8_t *); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d uu____0 = + libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element_ea( ring_element); deserialized_pk[i0] = uu____0; } - memcpy( - ret, deserialized_pk, - (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); -} - -/** -A monomorphic instance of libcrux_ml_kem.matrix.sample_matrix_A.closure.closure -with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, -libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const -generics -- K= 3 -*/ -static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_matrix_sample_matrix_A_closure_closure_78(size_t _j) { - return libcrux_ml_kem_polynomial_ZERO_89_ea(); -} - -/** -A monomorphic instance of libcrux_ml_kem.matrix.sample_matrix_A.closure -with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, -libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const -generics -- K= 3 -*/ -static inline void libcrux_ml_kem_matrix_sample_matrix_A_closure_4b( - size_t _i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U]) { - for (size_t i = (size_t)0U; i < (size_t)3U; i++) { - ret[i] = libcrux_ml_kem_polynomial_ZERO_89_ea(); - } } /** @@ -9438,67 +8198,61 @@ A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PortableHash with const generics - $3size_t */ -typedef struct libcrux_ml_kem_hash_functions_portable_PortableHash_58_s { - libcrux_sha3_generic_keccak_KeccakState_48 shake128_state[3U]; -} libcrux_ml_kem_hash_functions_portable_PortableHash_58; +typedef struct libcrux_ml_kem_hash_functions_portable_PortableHash_88_s { + libcrux_sha3_generic_keccak_KeccakState_17 shake128_state[3U]; +} libcrux_ml_kem_hash_functions_portable_PortableHash_88; /** A monomorphic instance of -libcrux_ml_kem.hash_functions.portable.shake128_init_absorb with const generics +libcrux_ml_kem.hash_functions.portable.shake128_init_absorb_final with const +generics - K= 3 */ -static KRML_MUSTINLINE libcrux_ml_kem_hash_functions_portable_PortableHash_58 -libcrux_ml_kem_hash_functions_portable_shake128_init_absorb_b7( - uint8_t input[3U][34U]) { - libcrux_sha3_generic_keccak_KeccakState_48 shake128_state[3U]; +static inline libcrux_ml_kem_hash_functions_portable_PortableHash_88 +libcrux_ml_kem_hash_functions_portable_shake128_init_absorb_final_e0( + uint8_t (*input)[34U]) { + libcrux_ml_kem_hash_functions_portable_PortableHash_88 shake128_state; + libcrux_sha3_generic_keccak_KeccakState_17 repeat_expression[3U]; for (size_t i = (size_t)0U; i < (size_t)3U; i++) { - shake128_state[i] = libcrux_sha3_portable_incremental_shake128_init(); + repeat_expression[i] = libcrux_sha3_portable_incremental_shake128_init(); } + memcpy(shake128_state.shake128_state, repeat_expression, + (size_t)3U * sizeof(libcrux_sha3_generic_keccak_KeccakState_17)); for (size_t i = (size_t)0U; i < (size_t)3U; i++) { size_t i0 = i; libcrux_sha3_portable_incremental_shake128_absorb_final( - &shake128_state[i0], + &shake128_state.shake128_state[i0], Eurydice_array_to_slice((size_t)34U, input[i0], uint8_t)); } - /* Passing arrays by value in Rust generates a copy in C */ - libcrux_sha3_generic_keccak_KeccakState_48 copy_of_shake128_state[3U]; - memcpy(copy_of_shake128_state, shake128_state, - (size_t)3U * sizeof(libcrux_sha3_generic_keccak_KeccakState_48)); - libcrux_ml_kem_hash_functions_portable_PortableHash_58 lit; - memcpy(lit.shake128_state, copy_of_shake128_state, - (size_t)3U * sizeof(libcrux_sha3_generic_keccak_KeccakState_48)); - return lit; + return shake128_state; } /** -This function found in impl {(libcrux_ml_kem::hash_functions::Hash for -libcrux_ml_kem::hash_functions::portable::PortableHash)} +This function found in impl {libcrux_ml_kem::hash_functions::Hash for +libcrux_ml_kem::hash_functions::portable::PortableHash} */ /** A monomorphic instance of -libcrux_ml_kem.hash_functions.portable.shake128_init_absorb_f1 with const +libcrux_ml_kem.hash_functions.portable.shake128_init_absorb_final_4a with const generics - K= 3 */ -static KRML_MUSTINLINE libcrux_ml_kem_hash_functions_portable_PortableHash_58 -libcrux_ml_kem_hash_functions_portable_shake128_init_absorb_f1_8c( - uint8_t input[3U][34U]) { - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_input[3U][34U]; - memcpy(copy_of_input, input, (size_t)3U * sizeof(uint8_t[34U])); - return libcrux_ml_kem_hash_functions_portable_shake128_init_absorb_b7( - copy_of_input); +static inline libcrux_ml_kem_hash_functions_portable_PortableHash_88 +libcrux_ml_kem_hash_functions_portable_shake128_init_absorb_final_4a_e0( + uint8_t (*input)[34U]) { + return libcrux_ml_kem_hash_functions_portable_shake128_init_absorb_final_e0( + input); } /** A monomorphic instance of -libcrux_ml_kem.hash_functions.portable.shake128_squeeze_three_blocks with const -generics +libcrux_ml_kem.hash_functions.portable.shake128_squeeze_first_three_blocks with +const generics - K= 3 */ -static KRML_MUSTINLINE void -libcrux_ml_kem_hash_functions_portable_shake128_squeeze_three_blocks_ca( - libcrux_ml_kem_hash_functions_portable_PortableHash_58 *st, +static inline void +libcrux_ml_kem_hash_functions_portable_shake128_squeeze_first_three_blocks_e0( + libcrux_ml_kem_hash_functions_portable_PortableHash_88 *st, uint8_t ret[3U][504U]) { uint8_t out[3U][504U] = {{0U}}; for (size_t i = (size_t)0U; i < (size_t)3U; i++) { @@ -9511,21 +8265,21 @@ libcrux_ml_kem_hash_functions_portable_shake128_squeeze_three_blocks_ca( } /** -This function found in impl {(libcrux_ml_kem::hash_functions::Hash for -libcrux_ml_kem::hash_functions::portable::PortableHash)} +This function found in impl {libcrux_ml_kem::hash_functions::Hash for +libcrux_ml_kem::hash_functions::portable::PortableHash} */ /** A monomorphic instance of -libcrux_ml_kem.hash_functions.portable.shake128_squeeze_three_blocks_f1 with -const generics +libcrux_ml_kem.hash_functions.portable.shake128_squeeze_first_three_blocks_4a +with const generics - K= 3 */ -static KRML_MUSTINLINE void -libcrux_ml_kem_hash_functions_portable_shake128_squeeze_three_blocks_f1_69( - libcrux_ml_kem_hash_functions_portable_PortableHash_58 *self, +static inline void +libcrux_ml_kem_hash_functions_portable_shake128_squeeze_first_three_blocks_4a_e0( + libcrux_ml_kem_hash_functions_portable_PortableHash_88 *self, uint8_t ret[3U][504U]) { - libcrux_ml_kem_hash_functions_portable_shake128_squeeze_three_blocks_ca(self, - ret); + libcrux_ml_kem_hash_functions_portable_shake128_squeeze_first_three_blocks_e0( + self, ret); } /** @@ -9577,8 +8331,8 @@ libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics - N= 504 */ static KRML_MUSTINLINE bool -libcrux_ml_kem_sampling_sample_from_uniform_distribution_next_db( - uint8_t randomness[3U][504U], size_t *sampled_coefficients, +libcrux_ml_kem_sampling_sample_from_uniform_distribution_next_89( + uint8_t (*randomness)[504U], size_t *sampled_coefficients, int16_t (*out)[272U]) { for (size_t i0 = (size_t)0U; i0 < (size_t)3U; i0++) { size_t i1 = i0; @@ -9586,15 +8340,15 @@ libcrux_ml_kem_sampling_sample_from_uniform_distribution_next_db( size_t r = i; if (sampled_coefficients[i1] < LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = - Eurydice_array_to_subslice2(randomness[i1], r * (size_t)24U, - r * (size_t)24U + (size_t)24U, uint8_t); - size_t sampled = libcrux_ml_kem_vector_portable_rej_sample_0d( - uu____0, Eurydice_array_to_subslice2( - out[i1], sampled_coefficients[i1], - sampled_coefficients[i1] + (size_t)16U, int16_t)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; + size_t sampled = libcrux_ml_kem_vector_portable_rej_sample_b8( + Eurydice_array_to_subslice3(randomness[i1], r * (size_t)24U, + r * (size_t)24U + (size_t)24U, + uint8_t *), + Eurydice_array_to_subslice3(out[i1], sampled_coefficients[i1], + sampled_coefficients[i1] + (size_t)16U, + int16_t *)); + size_t uu____0 = i1; + sampled_coefficients[uu____0] = sampled_coefficients[uu____0] + sampled; } } } @@ -9614,13 +8368,13 @@ libcrux_ml_kem_sampling_sample_from_uniform_distribution_next_db( /** A monomorphic instance of -libcrux_ml_kem.hash_functions.portable.shake128_squeeze_block with const +libcrux_ml_kem.hash_functions.portable.shake128_squeeze_next_block with const generics - K= 3 */ -static KRML_MUSTINLINE void -libcrux_ml_kem_hash_functions_portable_shake128_squeeze_block_dd( - libcrux_ml_kem_hash_functions_portable_PortableHash_58 *st, +static inline void +libcrux_ml_kem_hash_functions_portable_shake128_squeeze_next_block_e0( + libcrux_ml_kem_hash_functions_portable_PortableHash_88 *st, uint8_t ret[3U][168U]) { uint8_t out[3U][168U] = {{0U}}; for (size_t i = (size_t)0U; i < (size_t)3U; i++) { @@ -9633,20 +8387,21 @@ libcrux_ml_kem_hash_functions_portable_shake128_squeeze_block_dd( } /** -This function found in impl {(libcrux_ml_kem::hash_functions::Hash for -libcrux_ml_kem::hash_functions::portable::PortableHash)} +This function found in impl {libcrux_ml_kem::hash_functions::Hash for +libcrux_ml_kem::hash_functions::portable::PortableHash} */ /** A monomorphic instance of -libcrux_ml_kem.hash_functions.portable.shake128_squeeze_block_f1 with const +libcrux_ml_kem.hash_functions.portable.shake128_squeeze_next_block_4a with const generics - K= 3 */ -static KRML_MUSTINLINE void -libcrux_ml_kem_hash_functions_portable_shake128_squeeze_block_f1_60( - libcrux_ml_kem_hash_functions_portable_PortableHash_58 *self, +static inline void +libcrux_ml_kem_hash_functions_portable_shake128_squeeze_next_block_4a_e0( + libcrux_ml_kem_hash_functions_portable_PortableHash_88 *self, uint8_t ret[3U][168U]) { - libcrux_ml_kem_hash_functions_portable_shake128_squeeze_block_dd(self, ret); + libcrux_ml_kem_hash_functions_portable_shake128_squeeze_next_block_e0(self, + ret); } /** @@ -9698,8 +8453,8 @@ libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics - N= 168 */ static KRML_MUSTINLINE bool -libcrux_ml_kem_sampling_sample_from_uniform_distribution_next_db0( - uint8_t randomness[3U][168U], size_t *sampled_coefficients, +libcrux_ml_kem_sampling_sample_from_uniform_distribution_next_890( + uint8_t (*randomness)[168U], size_t *sampled_coefficients, int16_t (*out)[272U]) { for (size_t i0 = (size_t)0U; i0 < (size_t)3U; i0++) { size_t i1 = i0; @@ -9707,15 +8462,15 @@ libcrux_ml_kem_sampling_sample_from_uniform_distribution_next_db0( size_t r = i; if (sampled_coefficients[i1] < LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { - Eurydice_slice uu____0 = - Eurydice_array_to_subslice2(randomness[i1], r * (size_t)24U, - r * (size_t)24U + (size_t)24U, uint8_t); - size_t sampled = libcrux_ml_kem_vector_portable_rej_sample_0d( - uu____0, Eurydice_array_to_subslice2( - out[i1], sampled_coefficients[i1], - sampled_coefficients[i1] + (size_t)16U, int16_t)); - size_t uu____1 = i1; - sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; + size_t sampled = libcrux_ml_kem_vector_portable_rej_sample_b8( + Eurydice_array_to_subslice3(randomness[i1], r * (size_t)24U, + r * (size_t)24U + (size_t)24U, + uint8_t *), + Eurydice_array_to_subslice3(out[i1], sampled_coefficients[i1], + sampled_coefficients[i1] + (size_t)16U, + int16_t *)); + size_t uu____0 = i1; + sampled_coefficients[uu____0] = sampled_coefficients[uu____0] + sampled; } } } @@ -9734,42 +8489,64 @@ libcrux_ml_kem_sampling_sample_from_uniform_distribution_next_db0( } /** -This function found in impl -{libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0]} -*/ -/** -A monomorphic instance of libcrux_ml_kem.polynomial.from_i16_array_89 +A monomorphic instance of libcrux_ml_kem.polynomial.from_i16_array with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ -static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_polynomial_from_i16_array_89_c1(Eurydice_slice a) { - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 result = - libcrux_ml_kem_polynomial_ZERO_89_ea(); +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_polynomial_from_i16_array_ea(Eurydice_slice a) { + libcrux_ml_kem_polynomial_PolynomialRingElement_1d result = + libcrux_ml_kem_polynomial_ZERO_ea(); for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t i0 = i; libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = - libcrux_ml_kem_vector_portable_from_i16_array_0d( - Eurydice_slice_subslice2(a, i0 * (size_t)16U, - (i0 + (size_t)1U) * (size_t)16U, int16_t)); + libcrux_ml_kem_vector_portable_from_i16_array_b8( + Eurydice_slice_subslice3(a, i0 * (size_t)16U, + (i0 + (size_t)1U) * (size_t)16U, + int16_t *)); result.coefficients[i0] = uu____0; } return result; } /** -A monomorphic instance of libcrux_ml_kem.sampling.sample_from_xof.closure -with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, -libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const -generics -- K= 3 +This function found in impl +{libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0, +TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_ml_kem.polynomial.from_i16_array_d6 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_polynomial_from_i16_array_d6_ea(Eurydice_slice a) { + return libcrux_ml_kem_polynomial_from_i16_array_ea(a); +} + +/** +This function found in impl {core::ops::function::FnMut<(@Array), +libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0, +TraitClause@2]> for libcrux_ml_kem::sampling::sample_from_xof::closure[TraitClause@0, TraitClause@1, TraitClause@2, TraitClause@3]} +*/ +/** +A monomorphic instance of libcrux_ml_kem.sampling.sample_from_xof.call_mut_e7 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const +generics +- K= 3 */ -static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_sampling_sample_from_xof_closure_04(int16_t s[272U]) { - return libcrux_ml_kem_polynomial_from_i16_array_89_c1( - Eurydice_array_to_subslice2(s, (size_t)0U, (size_t)256U, int16_t)); +static inline libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_sampling_sample_from_xof_call_mut_e7_2b( + void **_, int16_t tupled_args[272U]) { + int16_t s[272U]; + memcpy(s, tupled_args, (size_t)272U * sizeof(int16_t)); + return libcrux_ml_kem_polynomial_from_i16_array_d6_ea( + Eurydice_array_to_subslice3(s, (size_t)0U, (size_t)256U, int16_t *)); } /** @@ -9779,51 +8556,43 @@ libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const generics - K= 3 */ -static KRML_MUSTINLINE void libcrux_ml_kem_sampling_sample_from_xof_3f( - uint8_t seeds[3U][34U], - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U]) { +static KRML_MUSTINLINE void libcrux_ml_kem_sampling_sample_from_xof_2b( + uint8_t (*seeds)[34U], + libcrux_ml_kem_polynomial_PolynomialRingElement_1d ret[3U]) { size_t sampled_coefficients[3U] = {0U}; int16_t out[3U][272U] = {{0U}}; - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_seeds[3U][34U]; - memcpy(copy_of_seeds, seeds, (size_t)3U * sizeof(uint8_t[34U])); - libcrux_ml_kem_hash_functions_portable_PortableHash_58 xof_state = - libcrux_ml_kem_hash_functions_portable_shake128_init_absorb_f1_8c( - copy_of_seeds); + libcrux_ml_kem_hash_functions_portable_PortableHash_88 xof_state = + libcrux_ml_kem_hash_functions_portable_shake128_init_absorb_final_4a_e0( + seeds); uint8_t randomness0[3U][504U]; - libcrux_ml_kem_hash_functions_portable_shake128_squeeze_three_blocks_f1_69( + libcrux_ml_kem_hash_functions_portable_shake128_squeeze_first_three_blocks_4a_e0( &xof_state, randomness0); - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_randomness0[3U][504U]; - memcpy(copy_of_randomness0, randomness0, (size_t)3U * sizeof(uint8_t[504U])); - bool done = libcrux_ml_kem_sampling_sample_from_uniform_distribution_next_db( - copy_of_randomness0, sampled_coefficients, out); + bool done = libcrux_ml_kem_sampling_sample_from_uniform_distribution_next_89( + randomness0, sampled_coefficients, out); while (true) { if (done) { break; } else { uint8_t randomness[3U][168U]; - libcrux_ml_kem_hash_functions_portable_shake128_squeeze_block_f1_60( + libcrux_ml_kem_hash_functions_portable_shake128_squeeze_next_block_4a_e0( &xof_state, randomness); - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_randomness[3U][168U]; - memcpy(copy_of_randomness, randomness, - (size_t)3U * sizeof(uint8_t[168U])); - done = libcrux_ml_kem_sampling_sample_from_uniform_distribution_next_db0( - copy_of_randomness, sampled_coefficients, out); + done = libcrux_ml_kem_sampling_sample_from_uniform_distribution_next_890( + randomness, sampled_coefficients, out); } } /* Passing arrays by value in Rust generates a copy in C */ int16_t copy_of_out[3U][272U]; memcpy(copy_of_out, out, (size_t)3U * sizeof(int16_t[272U])); - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret0[3U]; + libcrux_ml_kem_polynomial_PolynomialRingElement_1d ret0[3U]; for (size_t i = (size_t)0U; i < (size_t)3U; i++) { - ret0[i] = - libcrux_ml_kem_sampling_sample_from_xof_closure_04(copy_of_out[i]); + /* original Rust expression is not an lvalue in C */ + void *lvalue = (void *)0U; + ret0[i] = libcrux_ml_kem_sampling_sample_from_xof_call_mut_e7_2b( + &lvalue, copy_of_out[i]); } memcpy( ret, ret0, - (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); } /** @@ -9833,41 +8602,32 @@ libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const generics - K= 3 */ -static KRML_MUSTINLINE void libcrux_ml_kem_matrix_sample_matrix_A_38( - uint8_t seed[34U], bool transpose, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U][3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 A_transpose[3U][3U]; - for (size_t i = (size_t)0U; i < (size_t)3U; i++) { - libcrux_ml_kem_matrix_sample_matrix_A_closure_4b(i, A_transpose[i]); - } +static KRML_MUSTINLINE void libcrux_ml_kem_matrix_sample_matrix_A_2b( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d (*A_transpose)[3U], + uint8_t *seed, bool transpose) { for (size_t i0 = (size_t)0U; i0 < (size_t)3U; i0++) { size_t i1 = i0; - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_seed[34U]; - memcpy(copy_of_seed, seed, (size_t)34U * sizeof(uint8_t)); uint8_t seeds[3U][34U]; for (size_t i = (size_t)0U; i < (size_t)3U; i++) { - memcpy(seeds[i], copy_of_seed, (size_t)34U * sizeof(uint8_t)); + core_array__core__clone__Clone_for__Array_T__N___clone( + (size_t)34U, seed, seeds[i], uint8_t, void *); } for (size_t i = (size_t)0U; i < (size_t)3U; i++) { size_t j = i; seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j; } - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_seeds[3U][34U]; - memcpy(copy_of_seeds, seeds, (size_t)3U * sizeof(uint8_t[34U])); - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 sampled[3U]; - libcrux_ml_kem_sampling_sample_from_xof_3f(copy_of_seeds, sampled); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d sampled[3U]; + libcrux_ml_kem_sampling_sample_from_xof_2b(seeds, sampled); for (size_t i = (size_t)0U; i < Eurydice_slice_len( Eurydice_array_to_slice( (size_t)3U, sampled, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0), - libcrux_ml_kem_polynomial_PolynomialRingElement_f0); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d), + libcrux_ml_kem_polynomial_PolynomialRingElement_1d); i++) { size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 sample = sampled[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement_1d sample = sampled[j]; if (transpose) { A_transpose[j][i1] = sample; } else { @@ -9875,35 +8635,91 @@ static KRML_MUSTINLINE void libcrux_ml_kem_matrix_sample_matrix_A_38( } } } - memcpy(ret, A_transpose, - (size_t)3U * - sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0[3U])); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.build_unpacked_public_key_mut +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const +generics +- K= 3 +- T_AS_NTT_ENCODED_SIZE= 1152 +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_ind_cpa_build_unpacked_public_key_mut_3f( + Eurydice_slice public_key, + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_a0 + *unpacked_public_key) { + Eurydice_slice uu____0 = Eurydice_slice_subslice_to( + public_key, (size_t)1152U, uint8_t, size_t, uint8_t[]); + libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_1b( + uu____0, unpacked_public_key->t_as_ntt); + Eurydice_slice seed = Eurydice_slice_subslice_from( + public_key, (size_t)1152U, uint8_t, size_t, uint8_t[]); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d(*uu____1)[3U] = + unpacked_public_key->A; + uint8_t ret[34U]; + libcrux_ml_kem_utils_into_padded_array_b6(seed, ret); + libcrux_ml_kem_matrix_sample_matrix_A_2b(uu____1, ret, false); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.build_unpacked_public_key +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const +generics +- K= 3 +- T_AS_NTT_ENCODED_SIZE= 1152 +*/ +static KRML_MUSTINLINE + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_a0 + libcrux_ml_kem_ind_cpa_build_unpacked_public_key_3f( + Eurydice_slice public_key) { + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_a0 + unpacked_public_key = libcrux_ml_kem_ind_cpa_unpacked_default_8b_1b(); + libcrux_ml_kem_ind_cpa_build_unpacked_public_key_mut_3f(public_key, + &unpacked_public_key); + return unpacked_public_key; } /** A monomorphic instance of K. with types libcrux_ml_kem_polynomial_PolynomialRingElement -libcrux_ml_kem_vector_portable_vector_type_PortableVector[3size_t], uint8_t +libcrux_ml_kem_vector_portable_vector_type_PortableVector[3size_t], +libcrux_ml_kem_polynomial_PolynomialRingElement +libcrux_ml_kem_vector_portable_vector_type_PortableVector */ -typedef struct tuple_b0_s { - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 fst[3U]; - uint8_t snd; -} tuple_b0; +typedef struct tuple_ed_s { + libcrux_ml_kem_polynomial_PolynomialRingElement_1d fst[3U]; + libcrux_ml_kem_polynomial_PolynomialRingElement_1d snd; +} tuple_ed; /** -A monomorphic instance of -libcrux_ml_kem.ind_cpa.sample_vector_cbd_then_ntt.closure with types -libcrux_ml_kem_vector_portable_vector_type_PortableVector, +This function found in impl {core::ops::function::FnMut<(usize), +libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0, +TraitClause@2]> for libcrux_ml_kem::ind_cpa::encrypt_c1::closure[TraitClause@0, TraitClause@1, TraitClause@2, +TraitClause@3]} +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.encrypt_c1.call_mut_f1 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const generics - K= 3 -- ETA= 2 -- ETA_RANDOMNESS_SIZE= 128 +- C1_LEN= 960 +- U_COMPRESSION_FACTOR= 10 +- BLOCK_LEN= 320 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +- ETA2= 2 +- ETA2_RANDOMNESS_SIZE= 128 */ -static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_closure_f7(size_t _i) { - return libcrux_ml_kem_polynomial_ZERO_89_ea(); +static inline libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_ind_cpa_encrypt_c1_call_mut_f1_85(void **_, size_t tupled_args) { + return libcrux_ml_kem_polynomial_ZERO_d6_ea(); } /** @@ -9912,7 +8728,7 @@ with const generics - K= 3 - LEN= 128 */ -static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_PRFxN_c5( +static inline void libcrux_ml_kem_hash_functions_portable_PRFxN_41( uint8_t (*input)[33U], uint8_t ret[3U][128U]) { uint8_t out[3U][128U] = {{0U}}; for (size_t i = (size_t)0U; i < (size_t)3U; i++) { @@ -9925,18 +8741,18 @@ static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_PRFxN_c5( } /** -This function found in impl {(libcrux_ml_kem::hash_functions::Hash for -libcrux_ml_kem::hash_functions::portable::PortableHash)} +This function found in impl {libcrux_ml_kem::hash_functions::Hash for +libcrux_ml_kem::hash_functions::portable::PortableHash} */ /** -A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRFxN_f1 +A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRFxN_4a with const generics - K= 3 - LEN= 128 */ -static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_PRFxN_f1_93( +static inline void libcrux_ml_kem_hash_functions_portable_PRFxN_4a_41( uint8_t (*input)[33U], uint8_t ret[3U][128U]) { - libcrux_ml_kem_hash_functions_portable_PRFxN_c5(input, ret); + libcrux_ml_kem_hash_functions_portable_PRFxN_41(input, ret); } /** @@ -9994,16 +8810,16 @@ libcrux_ml_kem.sampling.sample_from_binomial_distribution_2 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ -static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_sampling_sample_from_binomial_distribution_2_85( +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_sampling_sample_from_binomial_distribution_2_ea( Eurydice_slice randomness) { int16_t sampled_i16s[256U] = {0U}; for (size_t i0 = (size_t)0U; i0 < Eurydice_slice_len(randomness, uint8_t) / (size_t)4U; i0++) { size_t chunk_number = i0; - Eurydice_slice byte_chunk = Eurydice_slice_subslice2( + Eurydice_slice byte_chunk = Eurydice_slice_subslice3( randomness, chunk_number * (size_t)4U, - chunk_number * (size_t)4U + (size_t)4U, uint8_t); + chunk_number * (size_t)4U + (size_t)4U, uint8_t *); uint32_t random_bits_as_u32 = (((uint32_t)Eurydice_slice_index(byte_chunk, (size_t)0U, uint8_t, uint8_t *) | @@ -10019,7 +8835,7 @@ libcrux_ml_kem_sampling_sample_from_binomial_distribution_2_85( uint32_t even_bits = random_bits_as_u32 & 1431655765U; uint32_t odd_bits = random_bits_as_u32 >> 1U & 1431655765U; uint32_t coin_toss_outcomes = even_bits + odd_bits; - for (uint32_t i = 0U; i < CORE_NUM__U32_8__BITS / 4U; i++) { + for (uint32_t i = 0U; i < 32U / 4U; i++) { uint32_t outcome_set = i; uint32_t outcome_set0 = outcome_set * 4U; int16_t outcome_1 = @@ -10030,52 +8846,7 @@ libcrux_ml_kem_sampling_sample_from_binomial_distribution_2_85( sampled_i16s[(size_t)8U * chunk_number + offset] = outcome_1 - outcome_2; } } - return libcrux_ml_kem_polynomial_from_i16_array_89_c1( - Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t)); -} - -/** -A monomorphic instance of -libcrux_ml_kem.sampling.sample_from_binomial_distribution_3 with types -libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics - -*/ -static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_sampling_sample_from_binomial_distribution_3_eb( - Eurydice_slice randomness) { - int16_t sampled_i16s[256U] = {0U}; - for (size_t i0 = (size_t)0U; - i0 < Eurydice_slice_len(randomness, uint8_t) / (size_t)3U; i0++) { - size_t chunk_number = i0; - Eurydice_slice byte_chunk = Eurydice_slice_subslice2( - randomness, chunk_number * (size_t)3U, - chunk_number * (size_t)3U + (size_t)3U, uint8_t); - uint32_t random_bits_as_u24 = - ((uint32_t)Eurydice_slice_index(byte_chunk, (size_t)0U, uint8_t, - uint8_t *) | - (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, uint8_t, - uint8_t *) - << 8U) | - (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, uint8_t, - uint8_t *) - << 16U; - uint32_t first_bits = random_bits_as_u24 & 2396745U; - uint32_t second_bits = random_bits_as_u24 >> 1U & 2396745U; - uint32_t third_bits = random_bits_as_u24 >> 2U & 2396745U; - uint32_t coin_toss_outcomes = first_bits + second_bits + third_bits; - for (int32_t i = (int32_t)0; i < (int32_t)24 / (int32_t)6; i++) { - int32_t outcome_set = i; - int32_t outcome_set0 = outcome_set * (int32_t)6; - int16_t outcome_1 = - (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 7U); - int16_t outcome_2 = (int16_t)(coin_toss_outcomes >> - (uint32_t)(outcome_set0 + (int32_t)3) & - 7U); - size_t offset = (size_t)(outcome_set0 / (int32_t)6); - sampled_i16s[(size_t)4U * chunk_number + offset] = outcome_1 - outcome_2; - } - } - return libcrux_ml_kem_polynomial_from_i16_array_89_c1( + return libcrux_ml_kem_polynomial_from_i16_array_d6_ea( Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t)); } @@ -10085,10 +8856,10 @@ libcrux_ml_kem.sampling.sample_from_binomial_distribution with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics - ETA= 2 */ -static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_sampling_sample_from_binomial_distribution_c6( +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_sampling_sample_from_binomial_distribution_a0( Eurydice_slice randomness) { - return libcrux_ml_kem_sampling_sample_from_binomial_distribution_2_85( + return libcrux_ml_kem_sampling_sample_from_binomial_distribution_2_ea( randomness); } @@ -10098,18 +8869,18 @@ with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ -static KRML_MUSTINLINE void libcrux_ml_kem_ntt_ntt_at_layer_7_f4( - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re) { +static KRML_MUSTINLINE void libcrux_ml_kem_ntt_ntt_at_layer_7_ea( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re) { size_t step = LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT / (size_t)2U; for (size_t i = (size_t)0U; i < step; i++) { size_t j = i; libcrux_ml_kem_vector_portable_vector_type_PortableVector t = - libcrux_ml_kem_vector_portable_multiply_by_constant_0d( + libcrux_ml_kem_vector_portable_multiply_by_constant_b8( re->coefficients[j + step], (int16_t)-1600); re->coefficients[j + step] = - libcrux_ml_kem_vector_portable_sub_0d(re->coefficients[j], &t); + libcrux_ml_kem_vector_portable_sub_b8(re->coefficients[j], &t); libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____1 = - libcrux_ml_kem_vector_portable_add_0d(re->coefficients[j], &t); + libcrux_ml_kem_vector_portable_add_b8(re->coefficients[j], &t); re->coefficients[j] = uu____1; } } @@ -10121,20 +8892,23 @@ with const generics */ static KRML_MUSTINLINE void -libcrux_ml_kem_ntt_ntt_binomially_sampled_ring_element_0f( - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re) { - libcrux_ml_kem_ntt_ntt_at_layer_7_f4(re); +libcrux_ml_kem_ntt_ntt_binomially_sampled_ring_element_ea( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re) { + libcrux_ml_kem_ntt_ntt_at_layer_7_ea(re); size_t zeta_i = (size_t)1U; - libcrux_ml_kem_ntt_ntt_at_layer_4_plus_51(&zeta_i, re, (size_t)6U, - (size_t)3U); - libcrux_ml_kem_ntt_ntt_at_layer_4_plus_51(&zeta_i, re, (size_t)5U, - (size_t)3U); - libcrux_ml_kem_ntt_ntt_at_layer_4_plus_51(&zeta_i, re, (size_t)4U, - (size_t)3U); - libcrux_ml_kem_ntt_ntt_at_layer_3_fd(&zeta_i, re, (size_t)3U, (size_t)3U); - libcrux_ml_kem_ntt_ntt_at_layer_2_ad(&zeta_i, re, (size_t)2U, (size_t)3U); - libcrux_ml_kem_ntt_ntt_at_layer_1_a2(&zeta_i, re, (size_t)1U, (size_t)3U); - libcrux_ml_kem_polynomial_poly_barrett_reduce_89_8b(re); + libcrux_ml_kem_ntt_ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)6U, + (size_t)11207U); + libcrux_ml_kem_ntt_ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)5U, + (size_t)11207U + (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_4_plus_ea( + &zeta_i, re, (size_t)4U, (size_t)11207U + (size_t)2U * (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_3_ea( + &zeta_i, re, (size_t)11207U + (size_t)3U * (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_2_ea( + &zeta_i, re, (size_t)11207U + (size_t)4U * (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_1_ea( + &zeta_i, re, (size_t)11207U + (size_t)5U * (size_t)3328U); + libcrux_ml_kem_polynomial_poly_barrett_reduce_d6_ea(re); } /** @@ -10150,59 +8924,54 @@ generics - ETA= 2 - ETA_RANDOMNESS_SIZE= 128 */ -static KRML_MUSTINLINE tuple_b0 -libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_fc(uint8_t prf_input[33U], - uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re_as_ntt[3U]; - for (size_t i = (size_t)0U; i < (size_t)3U; i++) { - re_as_ntt[i] = libcrux_ml_kem_polynomial_ZERO_89_ea(); - } - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_prf_input[33U]; - memcpy(copy_of_prf_input, prf_input, (size_t)33U * sizeof(uint8_t)); +static KRML_MUSTINLINE uint8_t +libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_3b( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re_as_ntt, + uint8_t *prf_input, uint8_t domain_separator) { uint8_t prf_inputs[3U][33U]; for (size_t i = (size_t)0U; i < (size_t)3U; i++) { - memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t)); - } - for (size_t i = (size_t)0U; i < (size_t)3U; i++) { - size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U; + core_array__core__clone__Clone_for__Array_T__N___clone( + (size_t)33U, prf_input, prf_inputs[i], uint8_t, void *); } + domain_separator = + libcrux_ml_kem_utils_prf_input_inc_e0(prf_inputs, domain_separator); uint8_t prf_outputs[3U][128U]; - libcrux_ml_kem_hash_functions_portable_PRFxN_f1_93(prf_inputs, prf_outputs); + libcrux_ml_kem_hash_functions_portable_PRFxN_4a_41(prf_inputs, prf_outputs); for (size_t i = (size_t)0U; i < (size_t)3U; i++) { size_t i0 = i; re_as_ntt[i0] = - libcrux_ml_kem_sampling_sample_from_binomial_distribution_c6( + libcrux_ml_kem_sampling_sample_from_binomial_distribution_a0( Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], uint8_t)); - libcrux_ml_kem_ntt_ntt_binomially_sampled_ring_element_0f(&re_as_ntt[i0]); + libcrux_ml_kem_ntt_ntt_binomially_sampled_ring_element_ea(&re_as_ntt[i0]); } - /* Passing arrays by value in Rust generates a copy in C */ - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 copy_of_re_as_ntt[3U]; - memcpy( - copy_of_re_as_ntt, re_as_ntt, - (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); - tuple_b0 lit; - memcpy( - lit.fst, copy_of_re_as_ntt, - (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); - lit.snd = domain_separator; - return lit; + return domain_separator; } /** -A monomorphic instance of libcrux_ml_kem.ind_cpa.sample_ring_element_cbd.closure +This function found in impl {core::ops::function::FnMut<(usize), +libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0, +TraitClause@2]> for libcrux_ml_kem::ind_cpa::encrypt_c1::closure#1[TraitClause@0, TraitClause@1, TraitClause@2, +TraitClause@3]} +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.encrypt_c1.call_mut_dd with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const generics - K= 3 -- ETA2_RANDOMNESS_SIZE= 128 +- C1_LEN= 960 +- U_COMPRESSION_FACTOR= 10 +- BLOCK_LEN= 320 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 - ETA2= 2 +- ETA2_RANDOMNESS_SIZE= 128 */ -static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_ind_cpa_sample_ring_element_cbd_closure_77(size_t _i) { - return libcrux_ml_kem_polynomial_ZERO_89_ea(); +static inline libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_ind_cpa_encrypt_c1_call_mut_dd_85(void **_, size_t tupled_args) { + return libcrux_ml_kem_polynomial_ZERO_d6_ea(); } /** @@ -10217,45 +8986,27 @@ generics - ETA2_RANDOMNESS_SIZE= 128 - ETA2= 2 */ -static KRML_MUSTINLINE tuple_b0 -libcrux_ml_kem_ind_cpa_sample_ring_element_cbd_ac(uint8_t prf_input[33U], - uint8_t domain_separator) { - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 error_1[3U]; - for (size_t i = (size_t)0U; i < (size_t)3U; i++) { - error_1[i] = libcrux_ml_kem_polynomial_ZERO_89_ea(); - } - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_prf_input[33U]; - memcpy(copy_of_prf_input, prf_input, (size_t)33U * sizeof(uint8_t)); +static KRML_MUSTINLINE uint8_t +libcrux_ml_kem_ind_cpa_sample_ring_element_cbd_3b( + uint8_t *prf_input, uint8_t domain_separator, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *error_1) { uint8_t prf_inputs[3U][33U]; for (size_t i = (size_t)0U; i < (size_t)3U; i++) { - memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t)); - } - for (size_t i = (size_t)0U; i < (size_t)3U; i++) { - size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U; + core_array__core__clone__Clone_for__Array_T__N___clone( + (size_t)33U, prf_input, prf_inputs[i], uint8_t, void *); } + domain_separator = + libcrux_ml_kem_utils_prf_input_inc_e0(prf_inputs, domain_separator); uint8_t prf_outputs[3U][128U]; - libcrux_ml_kem_hash_functions_portable_PRFxN_f1_93(prf_inputs, prf_outputs); + libcrux_ml_kem_hash_functions_portable_PRFxN_4a_41(prf_inputs, prf_outputs); for (size_t i = (size_t)0U; i < (size_t)3U; i++) { size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 uu____1 = - libcrux_ml_kem_sampling_sample_from_binomial_distribution_c6( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d uu____0 = + libcrux_ml_kem_sampling_sample_from_binomial_distribution_a0( Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], uint8_t)); - error_1[i0] = uu____1; + error_1[i0] = uu____0; } - /* Passing arrays by value in Rust generates a copy in C */ - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 copy_of_error_1[3U]; - memcpy( - copy_of_error_1, error_1, - (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); - tuple_b0 lit; - memcpy( - lit.fst, copy_of_error_1, - (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); - lit.snd = domain_separator; - return lit; + return domain_separator; } /** @@ -10263,7 +9014,7 @@ A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRF with const generics - LEN= 128 */ -static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_PRF_2b0( +static inline void libcrux_ml_kem_hash_functions_portable_PRF_a6( Eurydice_slice input, uint8_t ret[128U]) { uint8_t digest[128U] = {0U}; libcrux_sha3_portable_shake256( @@ -10272,59 +9023,80 @@ static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_PRF_2b0( } /** -This function found in impl {(libcrux_ml_kem::hash_functions::Hash for -libcrux_ml_kem::hash_functions::portable::PortableHash)} +This function found in impl {libcrux_ml_kem::hash_functions::Hash for +libcrux_ml_kem::hash_functions::portable::PortableHash} */ /** -A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRF_f1 +A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRF_4a with const generics - K= 3 - LEN= 128 */ -static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_PRF_f1_ee0( +static inline void libcrux_ml_kem_hash_functions_portable_PRF_4a_410( Eurydice_slice input, uint8_t ret[128U]) { - libcrux_ml_kem_hash_functions_portable_PRF_2b0(input, ret); + libcrux_ml_kem_hash_functions_portable_PRF_a6(input, ret); } /** -A monomorphic instance of libcrux_ml_kem.matrix.compute_vector_u.closure +This function found in impl {core::ops::function::FnMut<(usize), +libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0, +TraitClause@1]> for libcrux_ml_kem::matrix::compute_vector_u::closure[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_ml_kem.matrix.compute_vector_u.call_mut_a8 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics - K= 3 */ -static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_matrix_compute_vector_u_closure_d6(size_t _i) { - return libcrux_ml_kem_polynomial_ZERO_89_ea(); +static inline libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_matrix_compute_vector_u_call_mut_a8_1b(void **_, + size_t tupled_args) { + return libcrux_ml_kem_polynomial_ZERO_d6_ea(); } /** -This function found in impl -{libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0]} -*/ -/** -A monomorphic instance of libcrux_ml_kem.polynomial.add_error_reduce_89 +A monomorphic instance of libcrux_ml_kem.polynomial.add_error_reduce with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ -static KRML_MUSTINLINE void libcrux_ml_kem_polynomial_add_error_reduce_89_38( - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *self, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *error) { +static KRML_MUSTINLINE void libcrux_ml_kem_polynomial_add_error_reduce_ea( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *myself, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *error) { for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t j = i; libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient_normal_form = - libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_0d( - self->coefficients[j], (int16_t)1441); - libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = - libcrux_ml_kem_vector_portable_barrett_reduce_0d( - libcrux_ml_kem_vector_portable_add_0d(coefficient_normal_form, - &error->coefficients[j])); - self->coefficients[j] = uu____0; + libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_b8( + myself->coefficients[j], (int16_t)1441); + libcrux_ml_kem_vector_portable_vector_type_PortableVector sum = + libcrux_ml_kem_vector_portable_add_b8(coefficient_normal_form, + &error->coefficients[j]); + libcrux_ml_kem_vector_portable_vector_type_PortableVector red = + libcrux_ml_kem_vector_portable_barrett_reduce_b8(sum); + myself->coefficients[j] = red; } } +/** +This function found in impl +{libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0, +TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_ml_kem.polynomial.add_error_reduce_d6 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_polynomial_add_error_reduce_d6_ea( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *self, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *error) { + libcrux_ml_kem_polynomial_add_error_reduce_ea(self, error); +} + /** Compute u := InvertNTT(Aᵀ ◦ r̂) + e₁ */ @@ -10334,149 +9106,47 @@ with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics - K= 3 */ -static KRML_MUSTINLINE void libcrux_ml_kem_matrix_compute_vector_u_59( - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 (*a_as_ntt)[3U], - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *error_1, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 result[3U]; +static KRML_MUSTINLINE void libcrux_ml_kem_matrix_compute_vector_u_1b( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d (*a_as_ntt)[3U], + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *error_1, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement_1d result[3U]; for (size_t i = (size_t)0U; i < (size_t)3U; i++) { - result[i] = libcrux_ml_kem_polynomial_ZERO_89_ea(); + /* original Rust expression is not an lvalue in C */ + void *lvalue = (void *)0U; + result[i] = + libcrux_ml_kem_matrix_compute_vector_u_call_mut_a8_1b(&lvalue, i); } for (size_t i0 = (size_t)0U; i0 < Eurydice_slice_len( Eurydice_array_to_slice( (size_t)3U, a_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0[3U]), - libcrux_ml_kem_polynomial_PolynomialRingElement_f0[3U]); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d[3U]), + libcrux_ml_kem_polynomial_PolynomialRingElement_1d[3U]); i0++) { size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *row = a_as_ntt[i1]; + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *row = a_as_ntt[i1]; for (size_t i = (size_t)0U; i < Eurydice_slice_len( Eurydice_array_to_slice( (size_t)3U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0), - libcrux_ml_kem_polynomial_PolynomialRingElement_f0); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d), + libcrux_ml_kem_polynomial_PolynomialRingElement_1d); i++) { size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *a_element = &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 product = - libcrux_ml_kem_polynomial_ntt_multiply_89_2a(a_element, &r_as_ntt[j]); - libcrux_ml_kem_polynomial_add_to_ring_element_89_84(&result[i1], + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *a_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement_1d product = + libcrux_ml_kem_polynomial_ntt_multiply_d6_ea(a_element, &r_as_ntt[j]); + libcrux_ml_kem_polynomial_add_to_ring_element_d6_1b(&result[i1], &product); } - libcrux_ml_kem_invert_ntt_invert_ntt_montgomery_f6(&result[i1]); - libcrux_ml_kem_polynomial_add_error_reduce_89_38(&result[i1], &error_1[i1]); + libcrux_ml_kem_invert_ntt_invert_ntt_montgomery_1b(&result[i1]); + libcrux_ml_kem_polynomial_add_error_reduce_d6_ea(&result[i1], &error_1[i1]); } memcpy( ret, result, - (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); -} - -/** -A monomorphic instance of libcrux_ml_kem.vector.traits.decompress_1 -with types libcrux_ml_kem_vector_portable_vector_type_PortableVector -with const generics - -*/ -static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_traits_decompress_1_63( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { - libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = - libcrux_ml_kem_vector_portable_ZERO_0d(); - return libcrux_ml_kem_vector_portable_bitwise_and_with_constant_0d( - libcrux_ml_kem_vector_portable_sub_0d(uu____0, &v), (int16_t)1665); -} - -/** -A monomorphic instance of -libcrux_ml_kem.serialize.deserialize_then_decompress_message with types -libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics - -*/ -static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_serialize_deserialize_then_decompress_message_0d( - uint8_t serialized[32U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re = - libcrux_ml_kem_polynomial_ZERO_89_ea(); - for (size_t i = (size_t)0U; i < (size_t)16U; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_portable_vector_type_PortableVector - coefficient_compressed = - libcrux_ml_kem_vector_portable_deserialize_1_0d( - Eurydice_array_to_subslice2(serialized, (size_t)2U * i0, - (size_t)2U * i0 + (size_t)2U, - uint8_t)); - libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = - libcrux_ml_kem_vector_traits_decompress_1_63(coefficient_compressed); - re.coefficients[i0] = uu____0; - } - return re; -} - -/** -This function found in impl -{libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0]} -*/ -/** -A monomorphic instance of libcrux_ml_kem.polynomial.add_message_error_reduce_89 -with types libcrux_ml_kem_vector_portable_vector_type_PortableVector -with const generics - -*/ -static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_polynomial_add_message_error_reduce_89_ea( - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *self, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *message, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 result) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_portable_vector_type_PortableVector - coefficient_normal_form = - libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_0d( - result.coefficients[i0], (int16_t)1441); - libcrux_ml_kem_vector_portable_vector_type_PortableVector tmp = - libcrux_ml_kem_vector_portable_add_0d(self->coefficients[i0], - &message->coefficients[i0]); - libcrux_ml_kem_vector_portable_vector_type_PortableVector tmp0 = - libcrux_ml_kem_vector_portable_add_0d(coefficient_normal_form, &tmp); - libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = - libcrux_ml_kem_vector_portable_barrett_reduce_0d(tmp0); - result.coefficients[i0] = uu____0; - } - return result; -} - -/** - Compute InverseNTT(tᵀ ◦ r̂) + e₂ + message -*/ -/** -A monomorphic instance of libcrux_ml_kem.matrix.compute_ring_element_v -with types libcrux_ml_kem_vector_portable_vector_type_PortableVector -with const generics -- K= 3 -*/ -static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_matrix_compute_ring_element_v_54( - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *t_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *r_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *error_2, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *message) { - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 result = - libcrux_ml_kem_polynomial_ZERO_89_ea(); - for (size_t i = (size_t)0U; i < (size_t)3U; i++) { - size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 product = - libcrux_ml_kem_polynomial_ntt_multiply_89_2a(&t_as_ntt[i0], - &r_as_ntt[i0]); - libcrux_ml_kem_polynomial_add_to_ring_element_89_84(&result, &product); - } - libcrux_ml_kem_invert_ntt_invert_ntt_montgomery_f6(&result); - result = libcrux_ml_kem_polynomial_add_message_error_reduce_89_ea( - error_2, message, result); - return result; + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); } /** @@ -10485,32 +9155,33 @@ with const generics - COEFFICIENT_BITS= 10 */ static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_compress_compress_02( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { +libcrux_ml_kem_vector_portable_compress_compress_ef( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a) { for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { size_t i0 = i; - int16_t uu____0 = + int16_t uu____0 = libcrux_secrets_int_as_i16_f5( libcrux_ml_kem_vector_portable_compress_compress_ciphertext_coefficient( - (uint8_t)(int32_t)10, (uint16_t)v.elements[i0]); - v.elements[i0] = uu____0; + (uint8_t)(int32_t)10, + libcrux_secrets_int_as_u16_f5(a.elements[i0]))); + a.elements[i0] = uu____0; } - return v; + return a; } /** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} */ /** -A monomorphic instance of libcrux_ml_kem.vector.portable.compress_0d +A monomorphic instance of libcrux_ml_kem.vector.portable.compress_b8 with const generics - COEFFICIENT_BITS= 10 */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_compress_0d_28( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { - return libcrux_ml_kem_vector_portable_compress_compress_02(v); +libcrux_ml_kem_vector_portable_compress_b8_ef( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a) { + return libcrux_ml_kem_vector_portable_compress_compress_ef(a); } /** @@ -10520,83 +9191,22 @@ with const generics - OUT_LEN= 320 */ static KRML_MUSTINLINE void -libcrux_ml_kem_serialize_compress_then_serialize_10_fc( - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, uint8_t ret[320U]) { +libcrux_ml_kem_serialize_compress_then_serialize_10_ff( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re, uint8_t ret[320U]) { uint8_t serialized[320U] = {0U}; for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t i0 = i; libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = - libcrux_ml_kem_vector_portable_compress_0d_28( - libcrux_ml_kem_vector_traits_to_unsigned_representative_db( + libcrux_ml_kem_vector_portable_compress_b8_ef( + libcrux_ml_kem_serialize_to_unsigned_field_modulus_ea( re->coefficients[i0])); uint8_t bytes[20U]; - libcrux_ml_kem_vector_portable_serialize_10_0d(coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice2( - serialized, (size_t)20U * i0, (size_t)20U * i0 + (size_t)20U, uint8_t); + libcrux_ml_kem_vector_portable_serialize_10_b8(coefficient, bytes); Eurydice_slice_copy( - uu____0, Eurydice_array_to_slice((size_t)20U, bytes, uint8_t), uint8_t); - } - memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); -} - -/** -A monomorphic instance of libcrux_ml_kem.vector.portable.compress.compress -with const generics -- COEFFICIENT_BITS= 11 -*/ -static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_compress_compress_020( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { - size_t i0 = i; - int16_t uu____0 = - libcrux_ml_kem_vector_portable_compress_compress_ciphertext_coefficient( - (uint8_t)(int32_t)11, (uint16_t)v.elements[i0]); - v.elements[i0] = uu____0; - } - return v; -} - -/** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} -*/ -/** -A monomorphic instance of libcrux_ml_kem.vector.portable.compress_0d -with const generics -- COEFFICIENT_BITS= 11 -*/ -static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_compress_0d_280( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { - return libcrux_ml_kem_vector_portable_compress_compress_020(v); -} - -/** -A monomorphic instance of libcrux_ml_kem.serialize.compress_then_serialize_11 -with types libcrux_ml_kem_vector_portable_vector_type_PortableVector -with const generics -- OUT_LEN= 320 -*/ -static KRML_MUSTINLINE void -libcrux_ml_kem_serialize_compress_then_serialize_11_e1( - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, uint8_t ret[320U]) { - uint8_t serialized[320U] = {0U}; - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = - libcrux_ml_kem_vector_portable_compress_0d_280( - libcrux_ml_kem_vector_traits_to_unsigned_representative_db( - re->coefficients[i0])); - uint8_t bytes[22U]; - libcrux_ml_kem_vector_portable_serialize_11_0d(coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice2( - serialized, (size_t)22U * i0, (size_t)22U * i0 + (size_t)22U, uint8_t); - Eurydice_slice_copy( - uu____0, Eurydice_array_to_slice((size_t)22U, bytes, uint8_t), uint8_t); + Eurydice_array_to_subslice3(serialized, (size_t)20U * i0, + (size_t)20U * i0 + (size_t)20U, uint8_t *), + Eurydice_array_to_slice((size_t)20U, bytes, uint8_t), uint8_t); } memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); } @@ -10609,10 +9219,10 @@ libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics - OUT_LEN= 320 */ static KRML_MUSTINLINE void -libcrux_ml_kem_serialize_compress_then_serialize_ring_element_u_5f( - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, uint8_t ret[320U]) { +libcrux_ml_kem_serialize_compress_then_serialize_ring_element_u_fe( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re, uint8_t ret[320U]) { uint8_t uu____0[320U]; - libcrux_ml_kem_serialize_compress_then_serialize_10_fc(re, uu____0); + libcrux_ml_kem_serialize_compress_then_serialize_10_ff(re, uu____0); memcpy(ret, uu____0, (size_t)320U * sizeof(uint8_t)); } @@ -10628,23 +9238,23 @@ with const generics - COMPRESSION_FACTOR= 10 - BLOCK_LEN= 320 */ -static inline void libcrux_ml_kem_ind_cpa_compress_then_serialize_u_a7( - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 input[3U], +static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_compress_then_serialize_u_43( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d input[3U], Eurydice_slice out) { for (size_t i = (size_t)0U; i < Eurydice_slice_len( Eurydice_array_to_slice( (size_t)3U, input, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0), - libcrux_ml_kem_polynomial_PolynomialRingElement_f0); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d), + libcrux_ml_kem_polynomial_PolynomialRingElement_1d); i++) { size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re = input[i0]; - Eurydice_slice uu____0 = Eurydice_slice_subslice2( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d re = input[i0]; + Eurydice_slice uu____0 = Eurydice_slice_subslice3( out, i0 * ((size_t)960U / (size_t)3U), - (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U), uint8_t); + (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U), uint8_t *); uint8_t ret[320U]; - libcrux_ml_kem_serialize_compress_then_serialize_ring_element_u_5f(&re, + libcrux_ml_kem_serialize_compress_then_serialize_ring_element_u_fe(&re, ret); Eurydice_slice_copy( uu____0, Eurydice_array_to_slice((size_t)320U, ret, uint8_t), uint8_t); @@ -10652,122 +9262,232 @@ static inline void libcrux_ml_kem_ind_cpa_compress_then_serialize_u_a7( } /** -A monomorphic instance of libcrux_ml_kem.vector.portable.compress.compress -with const generics -- COEFFICIENT_BITS= 4 +A monomorphic instance of libcrux_ml_kem.ind_cpa.encrypt_c1 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const +generics +- K= 3 +- C1_LEN= 960 +- U_COMPRESSION_FACTOR= 10 +- BLOCK_LEN= 320 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +- ETA2= 2 +- ETA2_RANDOMNESS_SIZE= 128 */ -static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_compress_compress_021( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { - size_t i0 = i; - int16_t uu____0 = - libcrux_ml_kem_vector_portable_compress_compress_ciphertext_coefficient( - (uint8_t)(int32_t)4, (uint16_t)v.elements[i0]); - v.elements[i0] = uu____0; +static KRML_MUSTINLINE tuple_ed libcrux_ml_kem_ind_cpa_encrypt_c1_85( + Eurydice_slice randomness, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d (*matrix)[3U], + Eurydice_slice ciphertext) { + uint8_t prf_input[33U]; + libcrux_ml_kem_utils_into_padded_array_c8(randomness, prf_input); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d r_as_ntt[3U]; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + /* original Rust expression is not an lvalue in C */ + void *lvalue = (void *)0U; + r_as_ntt[i] = libcrux_ml_kem_ind_cpa_encrypt_c1_call_mut_f1_85(&lvalue, i); + } + uint8_t domain_separator0 = + libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_3b(r_as_ntt, prf_input, + 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d error_1[3U]; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + /* original Rust expression is not an lvalue in C */ + void *lvalue = (void *)0U; + error_1[i] = libcrux_ml_kem_ind_cpa_encrypt_c1_call_mut_dd_85(&lvalue, i); } - return v; -} - + uint8_t domain_separator = libcrux_ml_kem_ind_cpa_sample_ring_element_cbd_3b( + prf_input, domain_separator0, error_1); + prf_input[32U] = domain_separator; + uint8_t prf_output[128U]; + libcrux_ml_kem_hash_functions_portable_PRF_4a_410( + Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t), prf_output); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d error_2 = + libcrux_ml_kem_sampling_sample_from_binomial_distribution_a0( + Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d u[3U]; + libcrux_ml_kem_matrix_compute_vector_u_1b(matrix, r_as_ntt, error_1, u); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d uu____0[3U]; + memcpy( + uu____0, u, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); + libcrux_ml_kem_ind_cpa_compress_then_serialize_u_43(uu____0, ciphertext); + /* Passing arrays by value in Rust generates a copy in C */ + libcrux_ml_kem_polynomial_PolynomialRingElement_1d copy_of_r_as_ntt[3U]; + memcpy( + copy_of_r_as_ntt, r_as_ntt, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); + tuple_ed lit; + memcpy( + lit.fst, copy_of_r_as_ntt, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); + lit.snd = error_2; + return lit; +} + /** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +A monomorphic instance of +libcrux_ml_kem.serialize.deserialize_then_decompress_message with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics + */ +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_serialize_deserialize_then_decompress_message_ea( + uint8_t *serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement_1d re = + libcrux_ml_kem_polynomial_ZERO_d6_ea(); + for (size_t i = (size_t)0U; i < (size_t)16U; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_portable_vector_type_PortableVector + coefficient_compressed = + libcrux_ml_kem_vector_portable_deserialize_1_b8( + Eurydice_array_to_subslice3(serialized, (size_t)2U * i0, + (size_t)2U * i0 + (size_t)2U, + uint8_t *)); + libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = + libcrux_ml_kem_vector_portable_decompress_1_b8(coefficient_compressed); + re.coefficients[i0] = uu____0; + } + return re; +} + /** -A monomorphic instance of libcrux_ml_kem.vector.portable.compress_0d +A monomorphic instance of libcrux_ml_kem.polynomial.add_message_error_reduce +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics -- COEFFICIENT_BITS= 4 + */ -static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_compress_0d_281( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { - return libcrux_ml_kem_vector_portable_compress_compress_021(v); +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_polynomial_add_message_error_reduce_ea( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *myself, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *message, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d result) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_portable_vector_type_PortableVector + coefficient_normal_form = + libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_b8( + result.coefficients[i0], (int16_t)1441); + libcrux_ml_kem_vector_portable_vector_type_PortableVector sum1 = + libcrux_ml_kem_vector_portable_add_b8(myself->coefficients[i0], + &message->coefficients[i0]); + libcrux_ml_kem_vector_portable_vector_type_PortableVector sum2 = + libcrux_ml_kem_vector_portable_add_b8(coefficient_normal_form, &sum1); + libcrux_ml_kem_vector_portable_vector_type_PortableVector red = + libcrux_ml_kem_vector_portable_barrett_reduce_b8(sum2); + result.coefficients[i0] = red; + } + return result; } /** -A monomorphic instance of libcrux_ml_kem.serialize.compress_then_serialize_4 +This function found in impl +{libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0, +TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_ml_kem.polynomial.add_message_error_reduce_d6 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ -static KRML_MUSTINLINE void -libcrux_ml_kem_serialize_compress_then_serialize_4_9a( - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re, - Eurydice_slice serialized) { - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_polynomial_add_message_error_reduce_d6_ea( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *self, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *message, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d result) { + return libcrux_ml_kem_polynomial_add_message_error_reduce_ea(self, message, + result); +} + +/** + Compute InverseNTT(tᵀ ◦ r̂) + e₂ + message +*/ +/** +A monomorphic instance of libcrux_ml_kem.matrix.compute_ring_element_v +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_matrix_compute_ring_element_v_1b( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *t_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *error_2, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *message) { + libcrux_ml_kem_polynomial_PolynomialRingElement_1d result = + libcrux_ml_kem_polynomial_ZERO_d6_ea(); + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { size_t i0 = i; - libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = - libcrux_ml_kem_vector_portable_compress_0d_281( - libcrux_ml_kem_vector_traits_to_unsigned_representative_db( - re.coefficients[i0])); - uint8_t bytes[8U]; - libcrux_ml_kem_vector_portable_serialize_4_0d(coefficient, bytes); - Eurydice_slice_copy( - Eurydice_slice_subslice2(serialized, (size_t)8U * i0, - (size_t)8U * i0 + (size_t)8U, uint8_t), - Eurydice_array_to_slice((size_t)8U, bytes, uint8_t), uint8_t); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d product = + libcrux_ml_kem_polynomial_ntt_multiply_d6_ea(&t_as_ntt[i0], + &r_as_ntt[i0]); + libcrux_ml_kem_polynomial_add_to_ring_element_d6_1b(&result, &product); } + libcrux_ml_kem_invert_ntt_invert_ntt_montgomery_1b(&result); + return libcrux_ml_kem_polynomial_add_message_error_reduce_d6_ea( + error_2, message, result); } /** A monomorphic instance of libcrux_ml_kem.vector.portable.compress.compress with const generics -- COEFFICIENT_BITS= 5 +- COEFFICIENT_BITS= 4 */ static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_compress_compress_022( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { +libcrux_ml_kem_vector_portable_compress_compress_d1( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a) { for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { size_t i0 = i; - int16_t uu____0 = + int16_t uu____0 = libcrux_secrets_int_as_i16_f5( libcrux_ml_kem_vector_portable_compress_compress_ciphertext_coefficient( - (uint8_t)(int32_t)5, (uint16_t)v.elements[i0]); - v.elements[i0] = uu____0; + (uint8_t)(int32_t)4, + libcrux_secrets_int_as_u16_f5(a.elements[i0]))); + a.elements[i0] = uu____0; } - return v; + return a; } /** -This function found in impl {(libcrux_ml_kem::vector::traits::Operations for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +This function found in impl {libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector} */ /** -A monomorphic instance of libcrux_ml_kem.vector.portable.compress_0d +A monomorphic instance of libcrux_ml_kem.vector.portable.compress_b8 with const generics -- COEFFICIENT_BITS= 5 +- COEFFICIENT_BITS= 4 */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_compress_0d_282( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { - return libcrux_ml_kem_vector_portable_compress_compress_022(v); +libcrux_ml_kem_vector_portable_compress_b8_d1( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a) { + return libcrux_ml_kem_vector_portable_compress_compress_d1(a); } /** -A monomorphic instance of libcrux_ml_kem.serialize.compress_then_serialize_5 +A monomorphic instance of libcrux_ml_kem.serialize.compress_then_serialize_4 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ static KRML_MUSTINLINE void -libcrux_ml_kem_serialize_compress_then_serialize_5_1f( - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re, +libcrux_ml_kem_serialize_compress_then_serialize_4_ea( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d re, Eurydice_slice serialized) { for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t i0 = i; - libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficients = - libcrux_ml_kem_vector_portable_compress_0d_282( - libcrux_ml_kem_vector_traits_to_unsigned_representative_db( + libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = + libcrux_ml_kem_vector_portable_compress_b8_d1( + libcrux_ml_kem_serialize_to_unsigned_field_modulus_ea( re.coefficients[i0])); - uint8_t bytes[10U]; - libcrux_ml_kem_vector_portable_serialize_5_0d(coefficients, bytes); + uint8_t bytes[8U]; + libcrux_ml_kem_vector_portable_serialize_4_b8(coefficient, bytes); Eurydice_slice_copy( - Eurydice_slice_subslice2(serialized, (size_t)10U * i0, - (size_t)10U * i0 + (size_t)10U, uint8_t), - Eurydice_array_to_slice((size_t)10U, bytes, uint8_t), uint8_t); + Eurydice_slice_subslice3(serialized, (size_t)8U * i0, + (size_t)8U * i0 + (size_t)8U, uint8_t *), + Eurydice_array_to_slice((size_t)8U, bytes, uint8_t), uint8_t); } } @@ -10775,17 +9495,81 @@ libcrux_ml_kem_serialize_compress_then_serialize_5_1f( A monomorphic instance of libcrux_ml_kem.serialize.compress_then_serialize_ring_element_v with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- K= 3 - COMPRESSION_FACTOR= 4 - OUT_LEN= 128 */ static KRML_MUSTINLINE void -libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v_4e( - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re, Eurydice_slice out) { - libcrux_ml_kem_serialize_compress_then_serialize_4_9a(re, out); +libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v_6c( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d re, Eurydice_slice out) { + libcrux_ml_kem_serialize_compress_then_serialize_4_ea(re, out); } /** -A monomorphic instance of libcrux_ml_kem.ind_cpa.encrypt +A monomorphic instance of libcrux_ml_kem.ind_cpa.encrypt_c2 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +- V_COMPRESSION_FACTOR= 4 +- C2_LEN= 128 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_encrypt_c2_6c( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *t_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *error_2, + uint8_t *message, Eurydice_slice ciphertext) { + libcrux_ml_kem_polynomial_PolynomialRingElement_1d message_as_ring_element = + libcrux_ml_kem_serialize_deserialize_then_decompress_message_ea(message); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d v = + libcrux_ml_kem_matrix_compute_ring_element_v_1b( + t_as_ntt, r_as_ntt, error_2, &message_as_ring_element); + libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v_6c( + v, ciphertext); +} + +/** + This function implements Algorithm 13 of the + NIST FIPS 203 specification; this is the Kyber CPA-PKE encryption algorithm. + + Algorithm 13 is reproduced below: + + ```plaintext + Input: encryption key ekₚₖₑ ∈ 𝔹^{384k+32}. + Input: message m ∈ 𝔹^{32}. + Input: encryption randomness r ∈ 𝔹^{32}. + Output: ciphertext c ∈ 𝔹^{32(dᵤk + dᵥ)}. + + N ← 0 + t̂ ← ByteDecode₁₂(ekₚₖₑ[0:384k]) + ρ ← ekₚₖₑ[384k: 384k + 32] + for (i ← 0; i < k; i++) + for(j ← 0; j < k; j++) + Â[i,j] ← SampleNTT(XOF(ρ, i, j)) + end for + end for + for(i ← 0; i < k; i++) + r[i] ← SamplePolyCBD_{η₁}(PRF_{η₁}(r,N)) + N ← N + 1 + end for + for(i ← 0; i < k; i++) + e₁[i] ← SamplePolyCBD_{η₂}(PRF_{η₂}(r,N)) + N ← N + 1 + end for + e₂ ← SamplePolyCBD_{η₂}(PRF_{η₂}(r,N)) + r̂ ← NTT(r) + u ← NTT-¹(Âᵀ ◦ r̂) + e₁ + μ ← Decompress₁(ByteDecode₁(m))) + v ← NTT-¹(t̂ᵀ ◦ rˆ) + e₂ + μ + c₁ ← ByteEncode_{dᵤ}(Compress_{dᵤ}(u)) + c₂ ← ByteEncode_{dᵥ}(Compress_{dᵥ}(v)) + return c ← (c₁ ‖ c₂) + ``` + + The NIST FIPS 203 standard can be found at + . +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.encrypt_unpacked with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const generics @@ -10802,95 +9586,83 @@ generics - ETA2= 2 - ETA2_RANDOMNESS_SIZE= 128 */ -static inline void libcrux_ml_kem_ind_cpa_encrypt_60(Eurydice_slice public_key, - uint8_t message[32U], - Eurydice_slice randomness, - uint8_t ret[1088U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 t_as_ntt[3U]; - libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_33( - Eurydice_slice_subslice_to(public_key, (size_t)1152U, uint8_t, size_t), - t_as_ntt); - Eurydice_slice seed = - Eurydice_slice_subslice_from(public_key, (size_t)1152U, uint8_t, size_t); - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 A[3U][3U]; - uint8_t ret0[34U]; - libcrux_ml_kem_utils_into_padded_array_ea1(seed, ret0); - libcrux_ml_kem_matrix_sample_matrix_A_38(ret0, false, A); - uint8_t prf_input[33U]; - libcrux_ml_kem_utils_into_padded_array_ea2(randomness, prf_input); - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_prf_input0[33U]; - memcpy(copy_of_prf_input0, prf_input, (size_t)33U * sizeof(uint8_t)); - tuple_b0 uu____1 = libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_fc( - copy_of_prf_input0, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 r_as_ntt[3U]; - memcpy( - r_as_ntt, uu____1.fst, - (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); - uint8_t domain_separator0 = uu____1.snd; - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_prf_input[33U]; - memcpy(copy_of_prf_input, prf_input, (size_t)33U * sizeof(uint8_t)); - tuple_b0 uu____3 = libcrux_ml_kem_ind_cpa_sample_ring_element_cbd_ac( - copy_of_prf_input, domain_separator0); - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 error_1[3U]; - memcpy( - error_1, uu____3.fst, - (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); - uint8_t domain_separator = uu____3.snd; - prf_input[32U] = domain_separator; - uint8_t prf_output[128U]; - libcrux_ml_kem_hash_functions_portable_PRF_f1_ee0( - Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t), prf_output); - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 error_2 = - libcrux_ml_kem_sampling_sample_from_binomial_distribution_c6( - Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 u[3U]; - libcrux_ml_kem_matrix_compute_vector_u_59(A, r_as_ntt, error_1, u); - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_message[32U]; - memcpy(copy_of_message, message, (size_t)32U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 message_as_ring_element = - libcrux_ml_kem_serialize_deserialize_then_decompress_message_0d( - copy_of_message); - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 v = - libcrux_ml_kem_matrix_compute_ring_element_v_54( - t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); +static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_encrypt_unpacked_2a( + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_a0 *public_key, + uint8_t *message, Eurydice_slice randomness, uint8_t ret[1088U]) { uint8_t ciphertext[1088U] = {0U}; - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 uu____5[3U]; + tuple_ed uu____0 = libcrux_ml_kem_ind_cpa_encrypt_c1_85( + randomness, public_key->A, + Eurydice_array_to_subslice3(ciphertext, (size_t)0U, (size_t)960U, + uint8_t *)); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d r_as_ntt[3U]; memcpy( - uu____5, u, - (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); - libcrux_ml_kem_ind_cpa_compress_then_serialize_u_a7( - uu____5, Eurydice_array_to_subslice2(ciphertext, (size_t)0U, (size_t)960U, - uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 uu____6 = v; - libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v_4e( - uu____6, Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, - (size_t)960U, uint8_t, size_t)); + r_as_ntt, uu____0.fst, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d error_2 = uu____0.snd; + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *uu____1 = + public_key->t_as_ntt; + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *uu____2 = r_as_ntt; + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *uu____3 = &error_2; + uint8_t *uu____4 = message; + libcrux_ml_kem_ind_cpa_encrypt_c2_6c( + uu____1, uu____2, uu____3, uu____4, + Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, (size_t)960U, + uint8_t, size_t, uint8_t[])); memcpy(ret, ciphertext, (size_t)1088U * sizeof(uint8_t)); } /** -This function found in impl {(libcrux_ml_kem::variant::Variant for -libcrux_ml_kem::variant::MlKem)#1} +A monomorphic instance of libcrux_ml_kem.ind_cpa.encrypt +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const +generics +- K= 3 +- CIPHERTEXT_SIZE= 1088 +- T_AS_NTT_ENCODED_SIZE= 1152 +- C1_LEN= 960 +- C2_LEN= 128 +- U_COMPRESSION_FACTOR= 10 +- V_COMPRESSION_FACTOR= 4 +- BLOCK_LEN= 320 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +- ETA2= 2 +- ETA2_RANDOMNESS_SIZE= 128 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_encrypt_2a( + Eurydice_slice public_key, uint8_t *message, Eurydice_slice randomness, + uint8_t ret[1088U]) { + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_a0 + unpacked_public_key = + libcrux_ml_kem_ind_cpa_build_unpacked_public_key_3f(public_key); + uint8_t ret0[1088U]; + libcrux_ml_kem_ind_cpa_encrypt_unpacked_2a(&unpacked_public_key, message, + randomness, ret0); + memcpy(ret, ret0, (size_t)1088U * sizeof(uint8_t)); +} + +/** +This function found in impl {libcrux_ml_kem::variant::Variant for +libcrux_ml_kem::variant::MlKem} */ /** -A monomorphic instance of libcrux_ml_kem.variant.kdf_d8 +A monomorphic instance of libcrux_ml_kem.variant.kdf_39 with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const generics - K= 3 - CIPHERTEXT_SIZE= 1088 */ -static KRML_MUSTINLINE void libcrux_ml_kem_variant_kdf_d8_41( - Eurydice_slice shared_secret, libcrux_ml_kem_mlkem768_MlKem768Ciphertext *_, - uint8_t ret[32U]) { +static KRML_MUSTINLINE void libcrux_ml_kem_variant_kdf_39_d6( + Eurydice_slice shared_secret, uint8_t *_, uint8_t ret[32U]) { uint8_t out[32U] = {0U}; Eurydice_slice_copy(Eurydice_array_to_slice((size_t)32U, out, uint8_t), shared_secret, uint8_t); memcpy(ret, out, (size_t)32U * sizeof(uint8_t)); } +/** + This code verifies on some machines, runs out of memory on others +*/ /** A monomorphic instance of libcrux_ml_kem.ind_cca.decapsulate with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, @@ -10913,71 +9685,63 @@ libcrux_ml_kem_variant_MlKem with const generics - ETA2_RANDOMNESS_SIZE= 128 - IMPLICIT_REJECTION_HASH_INPUT_SIZE= 1120 */ -static inline void libcrux_ml_kem_ind_cca_decapsulate_70( - libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key, +static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_decapsulate_62( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { - Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at( - Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t), - (size_t)1152U, uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice_uint8_t_x4 uu____0 = + libcrux_ml_kem_types_unpack_private_key_b4( + Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t)); Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( - secret_key0, (size_t)1184U, uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - Eurydice_slice_uint8_t_x2 uu____2 = Eurydice_slice_split_at( - secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - Eurydice_slice_uint8_t_x2); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; + Eurydice_slice ind_cpa_public_key = uu____0.snd; + Eurydice_slice ind_cpa_public_key_hash = uu____0.thd; + Eurydice_slice implicit_rejection_value = uu____0.f3; uint8_t decrypted[32U]; - libcrux_ml_kem_ind_cpa_decrypt_43(ind_cpa_secret_key, ciphertext->value, + libcrux_ml_kem_ind_cpa_decrypt_42(ind_cpa_secret_key, ciphertext->value, decrypted); uint8_t to_hash0[64U]; - libcrux_ml_kem_utils_into_padded_array_ea( + libcrux_ml_kem_utils_into_padded_array_24( Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t), to_hash0); Eurydice_slice_copy( Eurydice_array_to_subslice_from( (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t), + uint8_t, size_t, uint8_t[]), ind_cpa_public_key_hash, uint8_t); uint8_t hashed[64U]; - libcrux_ml_kem_hash_functions_portable_G_f1_e4( + libcrux_ml_kem_hash_functions_portable_G_4a_e0( Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t), hashed); - Eurydice_slice_uint8_t_x2 uu____3 = Eurydice_slice_split_at( + Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice shared_secret0 = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; + Eurydice_slice shared_secret0 = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; uint8_t to_hash[1120U]; - libcrux_ml_kem_utils_into_padded_array_ea0(implicit_rejection_value, to_hash); - Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + libcrux_ml_kem_utils_into_padded_array_15(implicit_rejection_value, to_hash); + Eurydice_slice uu____2 = Eurydice_array_to_subslice_from( (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t); - Eurydice_slice_copy(uu____4, libcrux_ml_kem_types_as_ref_00_24(ciphertext), + uint8_t, size_t, uint8_t[]); + Eurydice_slice_copy(uu____2, libcrux_ml_kem_types_as_ref_d3_80(ciphertext), uint8_t); uint8_t implicit_rejection_shared_secret0[32U]; - libcrux_ml_kem_hash_functions_portable_PRF_f1_ee( + libcrux_ml_kem_hash_functions_portable_PRF_4a_41( Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t), implicit_rejection_shared_secret0); - Eurydice_slice uu____5 = ind_cpa_public_key; - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_decrypted[32U]; - memcpy(copy_of_decrypted, decrypted, (size_t)32U * sizeof(uint8_t)); uint8_t expected_ciphertext[1088U]; - libcrux_ml_kem_ind_cpa_encrypt_60(uu____5, copy_of_decrypted, + libcrux_ml_kem_ind_cpa_encrypt_2a(ind_cpa_public_key, decrypted, pseudorandomness, expected_ciphertext); uint8_t implicit_rejection_shared_secret[32U]; - libcrux_ml_kem_variant_kdf_d8_41( + libcrux_ml_kem_variant_kdf_39_d6( Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret0, uint8_t), - ciphertext, implicit_rejection_shared_secret); + libcrux_ml_kem_types_as_slice_a9_80(ciphertext), + implicit_rejection_shared_secret); uint8_t shared_secret[32U]; - libcrux_ml_kem_variant_kdf_d8_41(shared_secret0, ciphertext, shared_secret); + libcrux_ml_kem_variant_kdf_39_d6( + shared_secret0, libcrux_ml_kem_types_as_slice_a9_80(ciphertext), + shared_secret); uint8_t ret0[32U]; libcrux_ml_kem_constant_time_ops_compare_ciphertexts_select_shared_secret_in_constant_time( - libcrux_ml_kem_types_as_ref_00_24(ciphertext), + libcrux_ml_kem_types_as_ref_d3_80(ciphertext), Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, uint8_t), Eurydice_array_to_slice((size_t)32U, shared_secret, uint8_t), Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, @@ -11010,10 +9774,10 @@ libcrux_ml_kem.ind_cca.instantiations.portable.decapsulate with const generics - IMPLICIT_REJECTION_HASH_INPUT_SIZE= 1120 */ static inline void -libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate_2e( - libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key, +libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate_35( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { - libcrux_ml_kem_ind_cca_decapsulate_70(private_key, ciphertext, ret); + libcrux_ml_kem_ind_cca_decapsulate_62(private_key, ciphertext, ret); } /** @@ -11024,23 +9788,23 @@ libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate_2e( [`MlKem768Ciphertext`]. */ static inline void libcrux_ml_kem_mlkem768_portable_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key, + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { - libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate_2e( + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate_35( private_key, ciphertext, ret); } /** -This function found in impl {(libcrux_ml_kem::variant::Variant for -libcrux_ml_kem::variant::MlKem)#1} +This function found in impl {libcrux_ml_kem::variant::Variant for +libcrux_ml_kem::variant::MlKem} */ /** -A monomorphic instance of libcrux_ml_kem.variant.entropy_preprocess_d8 +A monomorphic instance of libcrux_ml_kem.variant.entropy_preprocess_39 with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const generics - K= 3 */ -static KRML_MUSTINLINE void libcrux_ml_kem_variant_entropy_preprocess_d8_63( +static KRML_MUSTINLINE void libcrux_ml_kem_variant_entropy_preprocess_39_9c( Eurydice_slice randomness, uint8_t ret[32U]) { uint8_t out[32U] = {0U}; Eurydice_slice_copy(Eurydice_array_to_slice((size_t)32U, out, uint8_t), @@ -11049,15 +9813,15 @@ static KRML_MUSTINLINE void libcrux_ml_kem_variant_entropy_preprocess_d8_63( } /** -This function found in impl {(libcrux_ml_kem::hash_functions::Hash for -libcrux_ml_kem::hash_functions::portable::PortableHash)} +This function found in impl {libcrux_ml_kem::hash_functions::Hash for +libcrux_ml_kem::hash_functions::portable::PortableHash} */ /** -A monomorphic instance of libcrux_ml_kem.hash_functions.portable.H_f1 +A monomorphic instance of libcrux_ml_kem.hash_functions.portable.H_4a with const generics - K= 3 */ -static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_H_f1_1a( +static inline void libcrux_ml_kem_hash_functions_portable_H_4a_e0( Eurydice_slice input, uint8_t ret[32U]) { libcrux_ml_kem_hash_functions_portable_H(input, ret); } @@ -11075,34 +9839,33 @@ libcrux_ml_kem_variant_MlKem with const generics - C2_SIZE= 128 - VECTOR_U_COMPRESSION_FACTOR= 10 - VECTOR_V_COMPRESSION_FACTOR= 4 -- VECTOR_U_BLOCK_LEN= 320 +- C1_BLOCK_SIZE= 320 - ETA1= 2 - ETA1_RANDOMNESS_SIZE= 128 - ETA2= 2 - ETA2_RANDOMNESS_SIZE= 128 */ -static inline tuple_3c libcrux_ml_kem_ind_cca_encapsulate_cd( - libcrux_ml_kem_types_MlKemPublicKey_15 *public_key, - uint8_t randomness[32U]) { +static KRML_MUSTINLINE tuple_c2 libcrux_ml_kem_ind_cca_encapsulate_ca( + libcrux_ml_kem_types_MlKemPublicKey_30 *public_key, uint8_t *randomness) { uint8_t randomness0[32U]; - libcrux_ml_kem_variant_entropy_preprocess_d8_63( + libcrux_ml_kem_variant_entropy_preprocess_39_9c( Eurydice_array_to_slice((size_t)32U, randomness, uint8_t), randomness0); uint8_t to_hash[64U]; - libcrux_ml_kem_utils_into_padded_array_ea( + libcrux_ml_kem_utils_into_padded_array_24( Eurydice_array_to_slice((size_t)32U, randomness0, uint8_t), to_hash); Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - size_t); - uint8_t ret[32U]; - libcrux_ml_kem_hash_functions_portable_H_f1_1a( + size_t, uint8_t[]); + uint8_t ret0[32U]; + libcrux_ml_kem_hash_functions_portable_H_4a_e0( Eurydice_array_to_slice((size_t)1184U, - libcrux_ml_kem_types_as_slice_cb_50(public_key), + libcrux_ml_kem_types_as_slice_e6_d0(public_key), uint8_t), - ret); + ret0); Eurydice_slice_copy( - uu____0, Eurydice_array_to_slice((size_t)32U, ret, uint8_t), uint8_t); + uu____0, Eurydice_array_to_slice((size_t)32U, ret0, uint8_t), uint8_t); uint8_t hashed[64U]; - libcrux_ml_kem_hash_functions_portable_G_f1_e4( + libcrux_ml_kem_hash_functions_portable_G_4a_e0( Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t), hashed); Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), @@ -11110,30 +9873,20 @@ static inline tuple_3c libcrux_ml_kem_ind_cca_encapsulate_cd( Eurydice_slice_uint8_t_x2); Eurydice_slice shared_secret = uu____1.fst; Eurydice_slice pseudorandomness = uu____1.snd; - Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)1184U, libcrux_ml_kem_types_as_slice_cb_50(public_key), uint8_t); - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_randomness[32U]; - memcpy(copy_of_randomness, randomness0, (size_t)32U * sizeof(uint8_t)); uint8_t ciphertext[1088U]; - libcrux_ml_kem_ind_cpa_encrypt_60(uu____2, copy_of_randomness, - pseudorandomness, ciphertext); + libcrux_ml_kem_ind_cpa_encrypt_2a( + Eurydice_array_to_slice((size_t)1184U, + libcrux_ml_kem_types_as_slice_e6_d0(public_key), + uint8_t), + randomness0, pseudorandomness, ciphertext); /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_ciphertext[1088U]; memcpy(copy_of_ciphertext, ciphertext, (size_t)1088U * sizeof(uint8_t)); - libcrux_ml_kem_mlkem768_MlKem768Ciphertext ciphertext0 = - libcrux_ml_kem_types_from_01_9f(copy_of_ciphertext); - uint8_t shared_secret_array[32U]; - libcrux_ml_kem_variant_kdf_d8_41(shared_secret, &ciphertext0, - shared_secret_array); - libcrux_ml_kem_mlkem768_MlKem768Ciphertext uu____5 = ciphertext0; - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_shared_secret_array[32U]; - memcpy(copy_of_shared_secret_array, shared_secret_array, - (size_t)32U * sizeof(uint8_t)); - tuple_3c lit; - lit.fst = uu____5; - memcpy(lit.snd, copy_of_shared_secret_array, (size_t)32U * sizeof(uint8_t)); + tuple_c2 lit; + lit.fst = libcrux_ml_kem_types_from_e0_80(copy_of_ciphertext); + uint8_t ret[32U]; + libcrux_ml_kem_variant_kdf_39_d6(shared_secret, ciphertext, ret); + memcpy(lit.snd, ret, (size_t)32U * sizeof(uint8_t)); return lit; } @@ -11148,21 +9901,16 @@ libcrux_ml_kem.ind_cca.instantiations.portable.encapsulate with const generics - C2_SIZE= 128 - VECTOR_U_COMPRESSION_FACTOR= 10 - VECTOR_V_COMPRESSION_FACTOR= 4 -- VECTOR_U_BLOCK_LEN= 320 +- C1_BLOCK_SIZE= 320 - ETA1= 2 - ETA1_RANDOMNESS_SIZE= 128 - ETA2= 2 - ETA2_RANDOMNESS_SIZE= 128 */ -static inline tuple_3c -libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate_c6( - libcrux_ml_kem_types_MlKemPublicKey_15 *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey_15 *uu____0 = public_key; - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_randomness[32U]; - memcpy(copy_of_randomness, randomness, (size_t)32U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_encapsulate_cd(uu____0, copy_of_randomness); +static inline tuple_c2 +libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate_cd( + libcrux_ml_kem_types_MlKemPublicKey_30 *public_key, uint8_t *randomness) { + return libcrux_ml_kem_ind_cca_encapsulate_ca(public_key, randomness); } /** @@ -11172,298 +9920,413 @@ libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate_c6( The input is a reference to an [`MlKem768PublicKey`] and [`SHARED_SECRET_SIZE`] bytes of `randomness`. */ -static inline tuple_3c libcrux_ml_kem_mlkem768_portable_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey_15 *public_key, +static inline tuple_c2 libcrux_ml_kem_mlkem768_portable_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey_30 *public_key, uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey_15 *uu____0 = public_key; - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_randomness[32U]; - memcpy(copy_of_randomness, randomness, (size_t)32U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate_c6( - uu____0, copy_of_randomness); + return libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate_cd( + public_key, randomness); +} + +/** +This function found in impl {core::default::Default for +libcrux_ml_kem::ind_cpa::unpacked::IndCpaPrivateKeyUnpacked[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.unpacked.default_70 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +*/ +static inline libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_a0 +libcrux_ml_kem_ind_cpa_unpacked_default_70_1b(void) { + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_a0 lit; + libcrux_ml_kem_polynomial_PolynomialRingElement_1d repeat_expression[3U]; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + repeat_expression[i] = libcrux_ml_kem_polynomial_ZERO_d6_ea(); + } + memcpy( + lit.secret_as_ntt, repeat_expression, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); + return lit; } /** -This function found in impl {(libcrux_ml_kem::variant::Variant for -libcrux_ml_kem::variant::MlKem)#1} +This function found in impl {libcrux_ml_kem::variant::Variant for +libcrux_ml_kem::variant::MlKem} */ /** -A monomorphic instance of libcrux_ml_kem.variant.cpa_keygen_seed_d8 +A monomorphic instance of libcrux_ml_kem.variant.cpa_keygen_seed_39 with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const generics - K= 3 */ -static KRML_MUSTINLINE void libcrux_ml_kem_variant_cpa_keygen_seed_d8_0e( +static KRML_MUSTINLINE void libcrux_ml_kem_variant_cpa_keygen_seed_39_9c( Eurydice_slice key_generation_seed, uint8_t ret[64U]) { uint8_t seed[33U] = {0U}; Eurydice_slice_copy( - Eurydice_array_to_subslice2( + Eurydice_array_to_subslice3( seed, (size_t)0U, - LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t), + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t *), key_generation_seed, uint8_t); seed[LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE] = (uint8_t)(size_t)3U; uint8_t ret0[64U]; - libcrux_ml_kem_hash_functions_portable_G_f1_e4( + libcrux_ml_kem_hash_functions_portable_G_4a_e0( Eurydice_array_to_slice((size_t)33U, seed, uint8_t), ret0); memcpy(ret, ret0, (size_t)64U * sizeof(uint8_t)); } /** -A monomorphic instance of libcrux_ml_kem.matrix.compute_As_plus_e.closure -with types libcrux_ml_kem_vector_portable_vector_type_PortableVector -with const generics +This function found in impl {core::ops::function::FnMut<(usize), +libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0, +TraitClause@3]> for +libcrux_ml_kem::ind_cpa::generate_keypair_unpacked::closure[TraitClause@0, TraitClause@1, +TraitClause@2, TraitClause@3, TraitClause@4, TraitClause@5]} +*/ +/** +A monomorphic instance of +libcrux_ml_kem.ind_cpa.generate_keypair_unpacked.call_mut_73 with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]], +libcrux_ml_kem_variant_MlKem with const generics - K= 3 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 */ -static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_matrix_compute_As_plus_e_closure_87(size_t _i) { - return libcrux_ml_kem_polynomial_ZERO_89_ea(); +static inline libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_ind_cpa_generate_keypair_unpacked_call_mut_73_1c( + void **_, size_t tupled_args) { + return libcrux_ml_kem_polynomial_ZERO_d6_ea(); } /** -A monomorphic instance of libcrux_ml_kem.vector.traits.to_standard_domain +A monomorphic instance of libcrux_ml_kem.polynomial.to_standard_domain with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ -static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_traits_to_standard_domain_59( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { - return libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_0d( - v, LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS); +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_polynomial_to_standard_domain_ea( + libcrux_ml_kem_vector_portable_vector_type_PortableVector vector) { + return libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_b8( + vector, + LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS); } /** -This function found in impl -{libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0]} -*/ -/** -A monomorphic instance of libcrux_ml_kem.polynomial.add_standard_error_reduce_89 +A monomorphic instance of libcrux_ml_kem.polynomial.add_standard_error_reduce with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ static KRML_MUSTINLINE void -libcrux_ml_kem_polynomial_add_standard_error_reduce_89_03( - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *self, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *error) { +libcrux_ml_kem_polynomial_add_standard_error_reduce_ea( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *myself, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *error) { for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { size_t j = i; libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient_normal_form = - libcrux_ml_kem_vector_traits_to_standard_domain_59( - self->coefficients[j]); - libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = - libcrux_ml_kem_vector_portable_barrett_reduce_0d( - libcrux_ml_kem_vector_portable_add_0d(coefficient_normal_form, - &error->coefficients[j])); - self->coefficients[j] = uu____0; + libcrux_ml_kem_polynomial_to_standard_domain_ea( + myself->coefficients[j]); + libcrux_ml_kem_vector_portable_vector_type_PortableVector sum = + libcrux_ml_kem_vector_portable_add_b8(coefficient_normal_form, + &error->coefficients[j]); + libcrux_ml_kem_vector_portable_vector_type_PortableVector red = + libcrux_ml_kem_vector_portable_barrett_reduce_b8(sum); + myself->coefficients[j] = red; } } /** - Compute  ◦ ŝ + ê +This function found in impl +{libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0, +TraitClause@1]} */ /** -A monomorphic instance of libcrux_ml_kem.matrix.compute_As_plus_e +A monomorphic instance of libcrux_ml_kem.polynomial.add_standard_error_reduce_d6 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics -- K= 3 -*/ -static KRML_MUSTINLINE void libcrux_ml_kem_matrix_compute_As_plus_e_60( - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 (*matrix_A)[3U], - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *s_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *error_as_ntt, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 result[3U]; - for (size_t i = (size_t)0U; i < (size_t)3U; i++) { - result[i] = libcrux_ml_kem_polynomial_ZERO_89_ea(); - } - for (size_t i0 = (size_t)0U; - i0 < Eurydice_slice_len( - Eurydice_array_to_slice( - (size_t)3U, matrix_A, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0[3U]), - libcrux_ml_kem_polynomial_PolynomialRingElement_f0[3U]); - i0++) { - size_t i1 = i0; - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *row = matrix_A[i1]; - for (size_t i = (size_t)0U; - i < Eurydice_slice_len( - Eurydice_array_to_slice( - (size_t)3U, row, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0), - libcrux_ml_kem_polynomial_PolynomialRingElement_f0); - i++) { - size_t j = i; - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *matrix_element = - &row[j]; - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 product = - libcrux_ml_kem_polynomial_ntt_multiply_89_2a(matrix_element, - &s_as_ntt[j]); - libcrux_ml_kem_polynomial_add_to_ring_element_89_84(&result[i1], - &product); - } - libcrux_ml_kem_polynomial_add_standard_error_reduce_89_03( - &result[i1], &error_as_ntt[i1]); - } - memcpy( - ret, result, - (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); -} - -/** -A monomorphic instance of -libcrux_ml_kem.serialize.serialize_uncompressed_ring_element with types -libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics */ static KRML_MUSTINLINE void -libcrux_ml_kem_serialize_serialize_uncompressed_ring_element_5b( - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, uint8_t ret[384U]) { - uint8_t serialized[384U] = {0U}; - for (size_t i = (size_t)0U; - i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { - size_t i0 = i; - libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = - libcrux_ml_kem_vector_traits_to_unsigned_representative_db( - re->coefficients[i0]); - uint8_t bytes[24U]; - libcrux_ml_kem_vector_portable_serialize_12_0d(coefficient, bytes); - Eurydice_slice uu____0 = Eurydice_array_to_subslice2( - serialized, (size_t)24U * i0, (size_t)24U * i0 + (size_t)24U, uint8_t); - Eurydice_slice_copy( - uu____0, Eurydice_array_to_slice((size_t)24U, bytes, uint8_t), uint8_t); - } - memcpy(ret, serialized, (size_t)384U * sizeof(uint8_t)); +libcrux_ml_kem_polynomial_add_standard_error_reduce_d6_ea( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *self, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *error) { + libcrux_ml_kem_polynomial_add_standard_error_reduce_ea(self, error); } /** - Call [`serialize_uncompressed_ring_element`] for each ring element. + Compute  ◦ ŝ + ê */ /** -A monomorphic instance of libcrux_ml_kem.ind_cpa.serialize_secret_key +A monomorphic instance of libcrux_ml_kem.matrix.compute_As_plus_e with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics - K= 3 -- OUT_LEN= 1152 */ -static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_serialize_secret_key_b5( - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *key, - uint8_t ret[1152U]) { - uint8_t out[1152U] = {0U}; +static KRML_MUSTINLINE void libcrux_ml_kem_matrix_compute_As_plus_e_1b( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *t_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d (*matrix_A)[3U], + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *s_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *error_as_ntt) { for (size_t i = (size_t)0U; i < Eurydice_slice_len( Eurydice_array_to_slice( - (size_t)3U, key, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0), - libcrux_ml_kem_polynomial_PolynomialRingElement_f0); + (size_t)3U, matrix_A, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d[3U]), + libcrux_ml_kem_polynomial_PolynomialRingElement_1d[3U]); i++) { size_t i0 = i; - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re = key[i0]; - Eurydice_slice uu____0 = Eurydice_array_to_subslice2( - out, i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - (i0 + (size_t)1U) * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - uint8_t); - uint8_t ret0[384U]; - libcrux_ml_kem_serialize_serialize_uncompressed_ring_element_5b(&re, ret0); - Eurydice_slice_copy( - uu____0, Eurydice_array_to_slice((size_t)384U, ret0, uint8_t), uint8_t); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *row = matrix_A[i0]; + libcrux_ml_kem_polynomial_PolynomialRingElement_1d uu____0 = + libcrux_ml_kem_polynomial_ZERO_d6_ea(); + t_as_ntt[i0] = uu____0; + for (size_t i1 = (size_t)0U; + i1 < Eurydice_slice_len( + Eurydice_array_to_slice( + (size_t)3U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d), + libcrux_ml_kem_polynomial_PolynomialRingElement_1d); + i1++) { + size_t j = i1; + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *matrix_element = + &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement_1d product = + libcrux_ml_kem_polynomial_ntt_multiply_d6_ea(matrix_element, + &s_as_ntt[j]); + libcrux_ml_kem_polynomial_add_to_ring_element_d6_1b(&t_as_ntt[i0], + &product); + } + libcrux_ml_kem_polynomial_add_standard_error_reduce_d6_ea( + &t_as_ntt[i0], &error_as_ntt[i0]); } - memcpy(ret, out, (size_t)1152U * sizeof(uint8_t)); } /** - Concatenate `t` and `ρ` into the public key. -*/ -/** -A monomorphic instance of libcrux_ml_kem.ind_cpa.serialize_public_key -with types libcrux_ml_kem_vector_portable_vector_type_PortableVector -with const generics -- K= 3 -- RANKED_BYTES_PER_RING_ELEMENT= 1152 -- PUBLIC_KEY_SIZE= 1184 -*/ -static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_serialize_public_key_79( - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *t_as_ntt, - Eurydice_slice seed_for_a, uint8_t ret[1184U]) { - uint8_t public_key_serialized[1184U] = {0U}; - Eurydice_slice uu____0 = Eurydice_array_to_subslice2( - public_key_serialized, (size_t)0U, (size_t)1152U, uint8_t); - uint8_t ret0[1152U]; - libcrux_ml_kem_ind_cpa_serialize_secret_key_b5(t_as_ntt, ret0); - Eurydice_slice_copy( - uu____0, Eurydice_array_to_slice((size_t)1152U, ret0, uint8_t), uint8_t); - Eurydice_slice_copy( - Eurydice_array_to_subslice_from((size_t)1184U, public_key_serialized, - (size_t)1152U, uint8_t, size_t), - seed_for_a, uint8_t); - memcpy(ret, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); -} + This function implements most of Algorithm 12 of the + NIST FIPS 203 specification; this is the Kyber CPA-PKE key generation + algorithm. + + We say "most of" since Algorithm 12 samples the required randomness within + the function itself, whereas this implementation expects it to be provided + through the `key_generation_seed` parameter. + + Algorithm 12 is reproduced below: + + ```plaintext + Output: encryption key ekₚₖₑ ∈ 𝔹^{384k+32}. + Output: decryption key dkₚₖₑ ∈ 𝔹^{384k}. + + d ←$ B + (ρ,σ) ← G(d) + N ← 0 + for (i ← 0; i < k; i++) + for(j ← 0; j < k; j++) + Â[i,j] ← SampleNTT(XOF(ρ, i, j)) + end for + end for + for(i ← 0; i < k; i++) + s[i] ← SamplePolyCBD_{η₁}(PRF_{η₁}(σ,N)) + N ← N + 1 + end for + for(i ← 0; i < k; i++) + e[i] ← SamplePolyCBD_{η₂}(PRF_{η₂}(σ,N)) + N ← N + 1 + end for + ŝ ← NTT(s) + ê ← NTT(e) + t̂ ← Â◦ŝ + ê + ekₚₖₑ ← ByteEncode₁₂(t̂) ‖ ρ + dkₚₖₑ ← ByteEncode₁₂(ŝ) + ``` + The NIST FIPS 203 standard can be found at + . +*/ /** -A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair +A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair_unpacked with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]], libcrux_ml_kem_variant_MlKem with const generics - K= 3 -- PRIVATE_KEY_SIZE= 1152 -- PUBLIC_KEY_SIZE= 1184 -- RANKED_BYTES_PER_RING_ELEMENT= 1152 - ETA1= 2 - ETA1_RANDOMNESS_SIZE= 128 */ -static inline libcrux_ml_kem_utils_extraction_helper_Keypair768 -libcrux_ml_kem_ind_cpa_generate_keypair_fc(Eurydice_slice key_generation_seed) { +static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_generate_keypair_unpacked_1c( + Eurydice_slice key_generation_seed, + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_a0 *private_key, + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_a0 *public_key) { uint8_t hashed[64U]; - libcrux_ml_kem_variant_cpa_keygen_seed_d8_0e(key_generation_seed, hashed); + libcrux_ml_kem_variant_cpa_keygen_seed_39_9c(key_generation_seed, hashed); Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at( Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), (size_t)32U, uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice seed_for_A0 = uu____0.fst; + Eurydice_slice seed_for_A = uu____0.fst; Eurydice_slice seed_for_secret_and_error = uu____0.snd; - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 A_transpose[3U][3U]; + libcrux_ml_kem_polynomial_PolynomialRingElement_1d(*uu____1)[3U] = + public_key->A; uint8_t ret[34U]; - libcrux_ml_kem_utils_into_padded_array_ea1(seed_for_A0, ret); - libcrux_ml_kem_matrix_sample_matrix_A_38(ret, true, A_transpose); + libcrux_ml_kem_utils_into_padded_array_b6(seed_for_A, ret); + libcrux_ml_kem_matrix_sample_matrix_A_2b(uu____1, ret, true); uint8_t prf_input[33U]; - libcrux_ml_kem_utils_into_padded_array_ea2(seed_for_secret_and_error, - prf_input); - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_prf_input0[33U]; - memcpy(copy_of_prf_input0, prf_input, (size_t)33U * sizeof(uint8_t)); - tuple_b0 uu____2 = libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_fc( - copy_of_prf_input0, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 secret_as_ntt[3U]; - memcpy( - secret_as_ntt, uu____2.fst, - (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); - uint8_t domain_separator = uu____2.snd; - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_prf_input[33U]; - memcpy(copy_of_prf_input, prf_input, (size_t)33U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 error_as_ntt[3U]; - memcpy( - error_as_ntt, - libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_fc(copy_of_prf_input, - domain_separator) - .fst, - (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 t_as_ntt[3U]; - libcrux_ml_kem_matrix_compute_As_plus_e_60(A_transpose, secret_as_ntt, - error_as_ntt, t_as_ntt); - uint8_t seed_for_A[32U]; - Result_00 dst; - Eurydice_slice_to_array2(&dst, seed_for_A0, Eurydice_slice, uint8_t[32U]); - unwrap_41_83(dst, seed_for_A); + libcrux_ml_kem_utils_into_padded_array_c8(seed_for_secret_and_error, + prf_input); + uint8_t domain_separator = + libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_3b( + private_key->secret_as_ntt, prf_input, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d error_as_ntt[3U]; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + /* original Rust expression is not an lvalue in C */ + void *lvalue = (void *)0U; + error_as_ntt[i] = + libcrux_ml_kem_ind_cpa_generate_keypair_unpacked_call_mut_73_1c(&lvalue, + i); + } + libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_3b(error_as_ntt, prf_input, + domain_separator); + libcrux_ml_kem_matrix_compute_As_plus_e_1b( + public_key->t_as_ntt, public_key->A, private_key->secret_as_ntt, + error_as_ntt); + uint8_t uu____2[32U]; + Result_fb dst; + Eurydice_slice_to_array2(&dst, seed_for_A, Eurydice_slice, uint8_t[32U], + TryFromSliceError); + unwrap_26_b3(dst, uu____2); + memcpy(public_key->seed_for_A, uu____2, (size_t)32U * sizeof(uint8_t)); +} + +/** +A monomorphic instance of +libcrux_ml_kem.serialize.serialize_uncompressed_ring_element with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics + +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_serialize_serialize_uncompressed_ring_element_ea( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re, uint8_t ret[384U]) { + uint8_t serialized[384U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = + libcrux_ml_kem_serialize_to_unsigned_field_modulus_ea( + re->coefficients[i0]); + uint8_t bytes[24U]; + libcrux_ml_kem_vector_portable_serialize_12_b8(coefficient, bytes); + Eurydice_slice_copy( + Eurydice_array_to_subslice3(serialized, (size_t)24U * i0, + (size_t)24U * i0 + (size_t)24U, uint8_t *), + Eurydice_array_to_slice((size_t)24U, bytes, uint8_t), uint8_t); + } + memcpy(ret, serialized, (size_t)384U * sizeof(uint8_t)); +} + +/** + Call [`serialize_uncompressed_ring_element`] for each ring element. +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.serialize_vector +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_serialize_vector_1b( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *key, + Eurydice_slice out) { + for (size_t i = (size_t)0U; + i < Eurydice_slice_len( + Eurydice_array_to_slice( + (size_t)3U, key, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d), + libcrux_ml_kem_polynomial_PolynomialRingElement_1d); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement_1d re = key[i0]; + Eurydice_slice uu____0 = Eurydice_slice_subslice3( + out, i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + (i0 + (size_t)1U) * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + uint8_t *); + uint8_t ret[384U]; + libcrux_ml_kem_serialize_serialize_uncompressed_ring_element_ea(&re, ret); + Eurydice_slice_copy( + uu____0, Eurydice_array_to_slice((size_t)384U, ret, uint8_t), uint8_t); + } +} + +/** + Concatenate `t` and `ρ` into the public key. +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.serialize_public_key_mut +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +- PUBLIC_KEY_SIZE= 1184 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_serialize_public_key_mut_89( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *t_as_ntt, + Eurydice_slice seed_for_a, uint8_t *serialized) { + libcrux_ml_kem_ind_cpa_serialize_vector_1b( + t_as_ntt, + Eurydice_array_to_subslice3( + serialized, (size_t)0U, + libcrux_ml_kem_constants_ranked_bytes_per_ring_element((size_t)3U), + uint8_t *)); + Eurydice_slice_copy( + Eurydice_array_to_subslice_from( + (size_t)1184U, serialized, + libcrux_ml_kem_constants_ranked_bytes_per_ring_element((size_t)3U), + uint8_t, size_t, uint8_t[]), + seed_for_a, uint8_t); +} + +/** + Concatenate `t` and `ρ` into the public key. +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.serialize_public_key +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +- PUBLIC_KEY_SIZE= 1184 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_serialize_public_key_89( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *t_as_ntt, + Eurydice_slice seed_for_a, uint8_t ret[1184U]) { + uint8_t public_key_serialized[1184U] = {0U}; + libcrux_ml_kem_ind_cpa_serialize_public_key_mut_89(t_as_ntt, seed_for_a, + public_key_serialized); + memcpy(ret, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); +} + +/** + Serialize the secret key from the unpacked key pair generation. +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.serialize_unpacked_secret_key +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +- PRIVATE_KEY_SIZE= 1152 +- PUBLIC_KEY_SIZE= 1184 +*/ +static inline libcrux_ml_kem_utils_extraction_helper_Keypair768 +libcrux_ml_kem_ind_cpa_serialize_unpacked_secret_key_6c( + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_a0 *public_key, + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_a0 *private_key) { uint8_t public_key_serialized[1184U]; - libcrux_ml_kem_ind_cpa_serialize_public_key_79( - t_as_ntt, Eurydice_array_to_slice((size_t)32U, seed_for_A, uint8_t), + libcrux_ml_kem_ind_cpa_serialize_public_key_89( + public_key->t_as_ntt, + Eurydice_array_to_slice((size_t)32U, public_key->seed_for_A, uint8_t), public_key_serialized); - uint8_t secret_key_serialized[1152U]; - libcrux_ml_kem_ind_cpa_serialize_secret_key_b5(secret_as_ntt, - secret_key_serialized); + uint8_t secret_key_serialized[1152U] = {0U}; + libcrux_ml_kem_ind_cpa_serialize_vector_1b( + private_key->secret_as_ntt, + Eurydice_array_to_slice((size_t)1152U, secret_key_serialized, uint8_t)); /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_secret_key_serialized[1152U]; memcpy(copy_of_secret_key_serialized, secret_key_serialized, @@ -11480,55 +10343,94 @@ libcrux_ml_kem_ind_cpa_generate_keypair_fc(Eurydice_slice key_generation_seed) { return lit; } +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]], +libcrux_ml_kem_variant_MlKem with const generics +- K= 3 +- PRIVATE_KEY_SIZE= 1152 +- PUBLIC_KEY_SIZE= 1184 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_utils_extraction_helper_Keypair768 +libcrux_ml_kem_ind_cpa_generate_keypair_ea(Eurydice_slice key_generation_seed) { + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_a0 private_key = + libcrux_ml_kem_ind_cpa_unpacked_default_70_1b(); + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_a0 public_key = + libcrux_ml_kem_ind_cpa_unpacked_default_8b_1b(); + libcrux_ml_kem_ind_cpa_generate_keypair_unpacked_1c( + key_generation_seed, &private_key, &public_key); + return libcrux_ml_kem_ind_cpa_serialize_unpacked_secret_key_6c(&public_key, + &private_key); +} + /** Serialize the secret key. */ /** -A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key +A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key_mut with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const generics - K= 3 - SERIALIZED_KEY_LEN= 2400 */ -static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_serialize_kem_secret_key_48( +static KRML_MUSTINLINE void +libcrux_ml_kem_ind_cca_serialize_kem_secret_key_mut_d6( Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { - uint8_t out[2400U] = {0U}; + Eurydice_slice implicit_rejection_value, uint8_t *serialized) { size_t pointer = (size_t)0U; - uint8_t *uu____0 = out; + uint8_t *uu____0 = serialized; size_t uu____1 = pointer; size_t uu____2 = pointer; Eurydice_slice_copy( - Eurydice_array_to_subslice2( + Eurydice_array_to_subslice3( uu____0, uu____1, uu____2 + Eurydice_slice_len(private_key, uint8_t), - uint8_t), + uint8_t *), private_key, uint8_t); pointer = pointer + Eurydice_slice_len(private_key, uint8_t); - uint8_t *uu____3 = out; + uint8_t *uu____3 = serialized; size_t uu____4 = pointer; size_t uu____5 = pointer; Eurydice_slice_copy( - Eurydice_array_to_subslice2( + Eurydice_array_to_subslice3( uu____3, uu____4, uu____5 + Eurydice_slice_len(public_key, uint8_t), - uint8_t), + uint8_t *), public_key, uint8_t); pointer = pointer + Eurydice_slice_len(public_key, uint8_t); - Eurydice_slice uu____6 = Eurydice_array_to_subslice2( - out, pointer, pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t); - uint8_t ret0[32U]; - libcrux_ml_kem_hash_functions_portable_H_f1_1a(public_key, ret0); + Eurydice_slice uu____6 = Eurydice_array_to_subslice3( + serialized, pointer, pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, + uint8_t *); + uint8_t ret[32U]; + libcrux_ml_kem_hash_functions_portable_H_4a_e0(public_key, ret); Eurydice_slice_copy( - uu____6, Eurydice_array_to_slice((size_t)32U, ret0, uint8_t), uint8_t); + uu____6, Eurydice_array_to_slice((size_t)32U, ret, uint8_t), uint8_t); pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; - uint8_t *uu____7 = out; + uint8_t *uu____7 = serialized; size_t uu____8 = pointer; size_t uu____9 = pointer; Eurydice_slice_copy( - Eurydice_array_to_subslice2( + Eurydice_array_to_subslice3( uu____7, uu____8, uu____9 + Eurydice_slice_len(implicit_rejection_value, uint8_t), - uint8_t), + uint8_t *), implicit_rejection_value, uint8_t); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key +with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] +with const generics +- K= 3 +- SERIALIZED_KEY_LEN= 2400 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_serialize_kem_secret_key_d6( + Eurydice_slice private_key, Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { + uint8_t out[2400U] = {0U}; + libcrux_ml_kem_ind_cca_serialize_kem_secret_key_mut_d6( + private_key, public_key, implicit_rejection_value, out); memcpy(ret, out, (size_t)2400U * sizeof(uint8_t)); } @@ -11549,27 +10451,26 @@ libcrux_ml_kem_variant_MlKem with const generics - CPA_PRIVATE_KEY_SIZE= 1152 - PRIVATE_KEY_SIZE= 2400 - PUBLIC_KEY_SIZE= 1184 -- BYTES_PER_RING_ELEMENT= 1152 - ETA1= 2 - ETA1_RANDOMNESS_SIZE= 128 */ -static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair -libcrux_ml_kem_ind_cca_generate_keypair_8c(uint8_t randomness[64U]) { - Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice2( +static KRML_MUSTINLINE libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_ind_cca_generate_keypair_15(uint8_t *randomness) { + Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice3( randomness, (size_t)0U, - LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t); + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t *); Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( (size_t)64U, randomness, LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, - size_t); + size_t, uint8_t[]); libcrux_ml_kem_utils_extraction_helper_Keypair768 uu____0 = - libcrux_ml_kem_ind_cpa_generate_keypair_fc(ind_cpa_keypair_randomness); + libcrux_ml_kem_ind_cpa_generate_keypair_ea(ind_cpa_keypair_randomness); uint8_t ind_cpa_private_key[1152U]; memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof(uint8_t)); uint8_t public_key[1184U]; memcpy(public_key, uu____0.snd, (size_t)1184U * sizeof(uint8_t)); uint8_t secret_key_serialized[2400U]; - libcrux_ml_kem_ind_cca_serialize_kem_secret_key_48( + libcrux_ml_kem_ind_cca_serialize_kem_secret_key_d6( Eurydice_array_to_slice((size_t)1152U, ind_cpa_private_key, uint8_t), Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t), implicit_rejection_value, secret_key_serialized); @@ -11577,14 +10478,14 @@ libcrux_ml_kem_ind_cca_generate_keypair_8c(uint8_t randomness[64U]) { uint8_t copy_of_secret_key_serialized[2400U]; memcpy(copy_of_secret_key_serialized, secret_key_serialized, (size_t)2400U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey_55 private_key = - libcrux_ml_kem_types_from_05_f2(copy_of_secret_key_serialized); - libcrux_ml_kem_types_MlKemPrivateKey_55 uu____2 = private_key; + libcrux_ml_kem_types_MlKemPrivateKey_d9 private_key = + libcrux_ml_kem_types_from_77_28(copy_of_secret_key_serialized); + libcrux_ml_kem_types_MlKemPrivateKey_d9 uu____2 = private_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_public_key[1184U]; memcpy(copy_of_public_key, public_key, (size_t)1184U * sizeof(uint8_t)); - return libcrux_ml_kem_types_from_17_35( - uu____2, libcrux_ml_kem_types_from_b6_da(copy_of_public_key)); + return libcrux_ml_kem_types_from_17_74( + uu____2, libcrux_ml_kem_types_from_fd_d0(copy_of_public_key)); } /** @@ -11598,17 +10499,13 @@ generics - CPA_PRIVATE_KEY_SIZE= 1152 - PRIVATE_KEY_SIZE= 2400 - PUBLIC_KEY_SIZE= 1184 -- BYTES_PER_RING_ELEMENT= 1152 - ETA1= 2 - ETA1_RANDOMNESS_SIZE= 128 */ static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair -libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair_d5( - uint8_t randomness[64U]) { - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_randomness[64U]; - memcpy(copy_of_randomness, randomness, (size_t)64U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_generate_keypair_8c(copy_of_randomness); +libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair_ce( + uint8_t *randomness) { + return libcrux_ml_kem_ind_cca_generate_keypair_15(randomness); } /** @@ -11616,155 +10513,273 @@ libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair_d5( */ static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair libcrux_ml_kem_mlkem768_portable_generate_key_pair(uint8_t randomness[64U]) { - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_randomness[64U]; - memcpy(copy_of_randomness, randomness, (size_t)64U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair_d5( - copy_of_randomness); + return libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair_ce( + randomness); } /** -This function found in impl {(libcrux_ml_kem::variant::Variant for -libcrux_ml_kem::variant::Kyber)} + Validate an ML-KEM private key. + + This implements the Hash check in 7.3 3. */ /** -A monomorphic instance of libcrux_ml_kem.variant.kdf_33 +A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key_only with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const generics - K= 3 -- CIPHERTEXT_SIZE= 1088 +- SECRET_KEY_SIZE= 2400 */ -static KRML_MUSTINLINE void libcrux_ml_kem_variant_kdf_33_f0( - Eurydice_slice shared_secret, - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { - uint8_t kdf_input[64U]; - libcrux_ml_kem_utils_into_padded_array_ea(shared_secret, kdf_input); - Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( - (size_t)64U, kdf_input, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - size_t); - uint8_t ret0[32U]; - libcrux_ml_kem_hash_functions_portable_H_f1_1a( - Eurydice_array_to_slice((size_t)1088U, - libcrux_ml_kem_types_as_slice_d4_1d(ciphertext), - uint8_t), - ret0); - Eurydice_slice_copy( - uu____0, Eurydice_array_to_slice((size_t)32U, ret0, uint8_t), uint8_t); - uint8_t ret1[32U]; - libcrux_ml_kem_hash_functions_portable_PRF_f1_ee( - Eurydice_array_to_slice((size_t)64U, kdf_input, uint8_t), ret1); - memcpy(ret, ret1, (size_t)32U * sizeof(uint8_t)); +static KRML_MUSTINLINE bool libcrux_ml_kem_ind_cca_validate_private_key_only_d6( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key) { + uint8_t t[32U]; + libcrux_ml_kem_hash_functions_portable_H_4a_e0( + Eurydice_array_to_subslice3(private_key->value, (size_t)384U * (size_t)3U, + (size_t)768U * (size_t)3U + (size_t)32U, + uint8_t *), + t); + Eurydice_slice expected = Eurydice_array_to_subslice3( + private_key->value, (size_t)768U * (size_t)3U + (size_t)32U, + (size_t)768U * (size_t)3U + (size_t)64U, uint8_t *); + return Eurydice_array_eq_slice((size_t)32U, t, &expected, uint8_t, bool); } /** -A monomorphic instance of libcrux_ml_kem.ind_cca.decapsulate -with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, -libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]], -libcrux_ml_kem_variant_Kyber with const generics + Validate an ML-KEM private key. + + This implements the Hash check in 7.3 3. + Note that the size checks in 7.2 1 and 2 are covered by the `SECRET_KEY_SIZE` + and `CIPHERTEXT_SIZE` in the `private_key` and `ciphertext` types. +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key +with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] +with const generics - K= 3 - SECRET_KEY_SIZE= 2400 -- CPA_SECRET_KEY_SIZE= 1152 -- PUBLIC_KEY_SIZE= 1184 - CIPHERTEXT_SIZE= 1088 -- T_AS_NTT_ENCODED_SIZE= 1152 -- C1_SIZE= 960 -- C2_SIZE= 128 -- VECTOR_U_COMPRESSION_FACTOR= 10 -- VECTOR_V_COMPRESSION_FACTOR= 4 -- C1_BLOCK_SIZE= 320 -- ETA1= 2 -- ETA1_RANDOMNESS_SIZE= 128 -- ETA2= 2 -- ETA2_RANDOMNESS_SIZE= 128 -- IMPLICIT_REJECTION_HASH_INPUT_SIZE= 1120 */ -static inline void libcrux_ml_kem_ind_cca_decapsulate_700( - libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key, - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { - Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at( - Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t), - (size_t)1152U, uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( - secret_key0, (size_t)1184U, uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - Eurydice_slice_uint8_t_x2 uu____2 = Eurydice_slice_split_at( - secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - Eurydice_slice_uint8_t_x2); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; - uint8_t decrypted[32U]; - libcrux_ml_kem_ind_cpa_decrypt_43(ind_cpa_secret_key, ciphertext->value, - decrypted); - uint8_t to_hash0[64U]; - libcrux_ml_kem_utils_into_padded_array_ea( - Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t), to_hash0); - Eurydice_slice_copy( - Eurydice_array_to_subslice_from( - (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t), - ind_cpa_public_key_hash, uint8_t); - uint8_t hashed[64U]; - libcrux_ml_kem_hash_functions_portable_G_f1_e4( - Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t), hashed); - Eurydice_slice_uint8_t_x2 uu____3 = Eurydice_slice_split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), - LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, - Eurydice_slice_uint8_t_x2); - Eurydice_slice shared_secret0 = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; - uint8_t to_hash[1120U]; - libcrux_ml_kem_utils_into_padded_array_ea0(implicit_rejection_value, to_hash); - Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( - (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, - uint8_t, size_t); - Eurydice_slice_copy(uu____4, libcrux_ml_kem_types_as_ref_00_24(ciphertext), - uint8_t); - uint8_t implicit_rejection_shared_secret0[32U]; - libcrux_ml_kem_hash_functions_portable_PRF_f1_ee( - Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t), - implicit_rejection_shared_secret0); - Eurydice_slice uu____5 = ind_cpa_public_key; - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_decrypted[32U]; - memcpy(copy_of_decrypted, decrypted, (size_t)32U * sizeof(uint8_t)); - uint8_t expected_ciphertext[1088U]; - libcrux_ml_kem_ind_cpa_encrypt_60(uu____5, copy_of_decrypted, - pseudorandomness, expected_ciphertext); - uint8_t implicit_rejection_shared_secret[32U]; - libcrux_ml_kem_variant_kdf_33_f0( - Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret0, - uint8_t), - ciphertext, implicit_rejection_shared_secret); - uint8_t shared_secret[32U]; - libcrux_ml_kem_variant_kdf_33_f0(shared_secret0, ciphertext, shared_secret); - uint8_t ret0[32U]; - libcrux_ml_kem_constant_time_ops_compare_ciphertexts_select_shared_secret_in_constant_time( - libcrux_ml_kem_types_as_ref_00_24(ciphertext), - Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, uint8_t), - Eurydice_array_to_slice((size_t)32U, shared_secret, uint8_t), - Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, - uint8_t), - ret0); - memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +static KRML_MUSTINLINE bool libcrux_ml_kem_ind_cca_validate_private_key_37( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *_ciphertext) { + return libcrux_ml_kem_ind_cca_validate_private_key_only_d6(private_key); } /** - Portable decapsulate + Private key validation */ /** A monomorphic instance of -libcrux_ml_kem.ind_cca.instantiations.portable.kyber_decapsulate with const +libcrux_ml_kem.ind_cca.instantiations.portable.validate_private_key with const generics - K= 3 - SECRET_KEY_SIZE= 2400 -- CPA_SECRET_KEY_SIZE= 1152 -- PUBLIC_KEY_SIZE= 1184 - CIPHERTEXT_SIZE= 1088 -- T_AS_NTT_ENCODED_SIZE= 1152 -- C1_SIZE= 960 +*/ +static KRML_MUSTINLINE bool +libcrux_ml_kem_ind_cca_instantiations_portable_validate_private_key_31( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext) { + return libcrux_ml_kem_ind_cca_validate_private_key_37(private_key, + ciphertext); +} + +/** + Validate a private key. + + Returns `true` if valid, and `false` otherwise. +*/ +static inline bool libcrux_ml_kem_mlkem768_portable_validate_private_key( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext) { + return libcrux_ml_kem_ind_cca_instantiations_portable_validate_private_key_31( + private_key, ciphertext); +} + +/** + Private key validation +*/ +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.instantiations.portable.validate_private_key_only with +const generics +- K= 3 +- SECRET_KEY_SIZE= 2400 +*/ +static KRML_MUSTINLINE bool +libcrux_ml_kem_ind_cca_instantiations_portable_validate_private_key_only_41( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key) { + return libcrux_ml_kem_ind_cca_validate_private_key_only_d6(private_key); +} + +/** + Validate the private key only. + + Returns `true` if valid, and `false` otherwise. +*/ +static inline bool libcrux_ml_kem_mlkem768_portable_validate_private_key_only( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key) { + return libcrux_ml_kem_ind_cca_instantiations_portable_validate_private_key_only_41( + private_key); +} + +/** +This function found in impl {core::ops::function::FnMut<(usize), +libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0, +TraitClause@1]> for +libcrux_ml_kem::serialize::deserialize_ring_elements_reduced_out::closure[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of +libcrux_ml_kem.serialize.deserialize_ring_elements_reduced_out.call_mut_0b with +types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const +generics +- K= 3 +*/ +static inline libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_out_call_mut_0b_1b( + void **_, size_t tupled_args) { + return libcrux_ml_kem_polynomial_ZERO_d6_ea(); +} + +/** + This function deserializes ring elements and reduces the result by the field + modulus. + + This function MUST NOT be used on secret inputs. +*/ +/** +A monomorphic instance of +libcrux_ml_kem.serialize.deserialize_ring_elements_reduced_out with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- K= 3 +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_out_1b( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement_1d deserialized_pk[3U]; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + /* original Rust expression is not an lvalue in C */ + void *lvalue = (void *)0U; + deserialized_pk[i] = + libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_out_call_mut_0b_1b( + &lvalue, i); + } + libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_1b( + public_key, deserialized_pk); + memcpy( + ret, deserialized_pk, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); +} + +/** + Validate an ML-KEM public key. + + This implements the Modulus check in 7.2 2. + Note that the size check in 7.2 1 is covered by the `PUBLIC_KEY_SIZE` in the + `public_key` type. +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.validate_public_key +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +- PUBLIC_KEY_SIZE= 1184 +*/ +static KRML_MUSTINLINE bool libcrux_ml_kem_ind_cca_validate_public_key_89( + uint8_t *public_key) { + libcrux_ml_kem_polynomial_PolynomialRingElement_1d deserialized_pk[3U]; + libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_out_1b( + Eurydice_array_to_subslice_to( + (size_t)1184U, public_key, + libcrux_ml_kem_constants_ranked_bytes_per_ring_element((size_t)3U), + uint8_t, size_t, uint8_t[]), + deserialized_pk); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *uu____0 = deserialized_pk; + uint8_t public_key_serialized[1184U]; + libcrux_ml_kem_ind_cpa_serialize_public_key_89( + uu____0, + Eurydice_array_to_subslice_from( + (size_t)1184U, public_key, + libcrux_ml_kem_constants_ranked_bytes_per_ring_element((size_t)3U), + uint8_t, size_t, uint8_t[]), + public_key_serialized); + return Eurydice_array_eq((size_t)1184U, public_key, public_key_serialized, + uint8_t); +} + +/** + Public key validation +*/ +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.instantiations.portable.validate_public_key with const +generics +- K= 3 +- PUBLIC_KEY_SIZE= 1184 +*/ +static KRML_MUSTINLINE bool +libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key_41( + uint8_t *public_key) { + return libcrux_ml_kem_ind_cca_validate_public_key_89(public_key); +} + +/** + Validate a public key. + + Returns `true` if valid, and `false` otherwise. +*/ +static inline bool libcrux_ml_kem_mlkem768_portable_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey_30 *public_key) { + return libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key_41( + public_key->value); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.unpacked.MlKemPublicKeyUnpacked +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- $3size_t +*/ +typedef struct libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0_s { + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_a0 ind_cpa_public_key; + uint8_t public_key_hash[32U]; +} libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0; + +typedef libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0 + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768PublicKeyUnpacked; + +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.unpacked.MlKemPrivateKeyUnpacked with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- $3size_t +*/ +typedef struct libcrux_ml_kem_ind_cca_unpacked_MlKemPrivateKeyUnpacked_a0_s { + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_a0 + ind_cpa_private_key; + uint8_t implicit_rejection_value[32U]; +} libcrux_ml_kem_ind_cca_unpacked_MlKemPrivateKeyUnpacked_a0; + +typedef struct + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked_s { + libcrux_ml_kem_ind_cca_unpacked_MlKemPrivateKeyUnpacked_a0 private_key; + libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0 public_key; +} libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked; + +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.unpacked.decapsulate +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const +generics +- K= 3 +- SECRET_KEY_SIZE= 2400 +- CPA_SECRET_KEY_SIZE= 1152 +- PUBLIC_KEY_SIZE= 1184 +- CIPHERTEXT_SIZE= 1088 +- T_AS_NTT_ENCODED_SIZE= 1152 +- C1_SIZE= 960 - C2_SIZE= 128 - VECTOR_U_COMPRESSION_FACTOR= 10 - VECTOR_V_COMPRESSION_FACTOR= 4 @@ -11775,47 +10790,135 @@ generics - ETA2_RANDOMNESS_SIZE= 128 - IMPLICIT_REJECTION_HASH_INPUT_SIZE= 1120 */ -static inline void -libcrux_ml_kem_ind_cca_instantiations_portable_kyber_decapsulate_fc( - libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key, +static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_unpacked_decapsulate_51( + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked *key_pair, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { + uint8_t decrypted[32U]; + libcrux_ml_kem_ind_cpa_decrypt_unpacked_42( + &key_pair->private_key.ind_cpa_private_key, ciphertext->value, decrypted); + uint8_t to_hash0[64U]; + libcrux_ml_kem_utils_into_padded_array_24( + Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t), to_hash0); + Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( + (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, uint8_t[]); + Eurydice_slice_copy( + uu____0, + Eurydice_array_to_slice((size_t)32U, key_pair->public_key.public_key_hash, + uint8_t), + uint8_t); + uint8_t hashed[64U]; + libcrux_ml_kem_hash_functions_portable_G_4a_e0( + Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t), hashed); + Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + Eurydice_slice_uint8_t_x2); + Eurydice_slice shared_secret = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; + uint8_t to_hash[1120U]; + libcrux_ml_kem_utils_into_padded_array_15( + Eurydice_array_to_slice( + (size_t)32U, key_pair->private_key.implicit_rejection_value, uint8_t), + to_hash); + Eurydice_slice uu____2 = Eurydice_array_to_subslice_from( + (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, uint8_t[]); + Eurydice_slice_copy(uu____2, libcrux_ml_kem_types_as_ref_d3_80(ciphertext), + uint8_t); + uint8_t implicit_rejection_shared_secret[32U]; + libcrux_ml_kem_hash_functions_portable_PRF_4a_41( + Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t), + implicit_rejection_shared_secret); + uint8_t expected_ciphertext[1088U]; + libcrux_ml_kem_ind_cpa_encrypt_unpacked_2a( + &key_pair->public_key.ind_cpa_public_key, decrypted, pseudorandomness, + expected_ciphertext); + uint8_t selector = + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time( + libcrux_ml_kem_types_as_ref_d3_80(ciphertext), + Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, uint8_t)); + uint8_t ret0[32U]; + libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( + shared_secret, + Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, + uint8_t), + selector, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +/** + Unpacked decapsulate +*/ +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.instantiations.portable.unpacked.decapsulate with const +generics +- K= 3 +- SECRET_KEY_SIZE= 2400 +- CPA_SECRET_KEY_SIZE= 1152 +- PUBLIC_KEY_SIZE= 1184 +- CIPHERTEXT_SIZE= 1088 +- T_AS_NTT_ENCODED_SIZE= 1152 +- C1_SIZE= 960 +- C2_SIZE= 128 +- VECTOR_U_COMPRESSION_FACTOR= 10 +- VECTOR_V_COMPRESSION_FACTOR= 4 +- C1_BLOCK_SIZE= 320 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +- ETA2= 2 +- ETA2_RANDOMNESS_SIZE= 128 +- IMPLICIT_REJECTION_HASH_INPUT_SIZE= 1120 +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_ind_cca_instantiations_portable_unpacked_decapsulate_35( + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked *key_pair, libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { - libcrux_ml_kem_ind_cca_decapsulate_700(private_key, ciphertext, ret); + libcrux_ml_kem_ind_cca_unpacked_decapsulate_51(key_pair, ciphertext, ret); } /** - Decapsulate Kyber 768 + Decapsulate ML-KEM 768 (unpacked) Generates an [`MlKemSharedSecret`]. - The input is a reference to an [`MlKem768PrivateKey`] and an - [`MlKem768Ciphertext`]. + The input is a reference to an unpacked key pair of type + [`MlKem768KeyPairUnpacked`] and an [`MlKem768Ciphertext`]. */ -static inline void libcrux_ml_kem_mlkem768_portable_kyber_decapsulate( - libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key, +static inline void libcrux_ml_kem_mlkem768_portable_unpacked_decapsulate( + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked + *private_key, libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { - libcrux_ml_kem_ind_cca_instantiations_portable_kyber_decapsulate_fc( + libcrux_ml_kem_ind_cca_instantiations_portable_unpacked_decapsulate_35( private_key, ciphertext, ret); } /** -This function found in impl {(libcrux_ml_kem::variant::Variant for -libcrux_ml_kem::variant::Kyber)} -*/ -/** -A monomorphic instance of libcrux_ml_kem.variant.entropy_preprocess_33 +A monomorphic instance of libcrux_ml_kem.ind_cca.unpacked.encaps_prepare with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const generics - K= 3 */ -static KRML_MUSTINLINE void libcrux_ml_kem_variant_entropy_preprocess_33_8a( - Eurydice_slice randomness, uint8_t ret[32U]) { - libcrux_ml_kem_hash_functions_portable_H_f1_1a(randomness, ret); +static inline void libcrux_ml_kem_ind_cca_unpacked_encaps_prepare_9c( + Eurydice_slice randomness, Eurydice_slice pk_hash, uint8_t ret[64U]) { + uint8_t to_hash[64U]; + libcrux_ml_kem_utils_into_padded_array_24(randomness, to_hash); + Eurydice_slice_copy( + Eurydice_array_to_subslice_from((size_t)64U, to_hash, + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, + uint8_t, size_t, uint8_t[]), + pk_hash, uint8_t); + uint8_t ret0[64U]; + libcrux_ml_kem_hash_functions_portable_G_4a_e0( + Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t), ret0); + memcpy(ret, ret0, (size_t)64U * sizeof(uint8_t)); } /** -A monomorphic instance of libcrux_ml_kem.ind_cca.encapsulate +A monomorphic instance of libcrux_ml_kem.ind_cca.unpacked.encapsulate with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, -libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]], -libcrux_ml_kem_variant_Kyber with const generics +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const +generics - K= 3 - CIPHERTEXT_SIZE= 1088 - PUBLIC_KEY_SIZE= 1184 @@ -11830,68 +10933,50 @@ libcrux_ml_kem_variant_Kyber with const generics - ETA2= 2 - ETA2_RANDOMNESS_SIZE= 128 */ -static inline tuple_3c libcrux_ml_kem_ind_cca_encapsulate_cd0( - libcrux_ml_kem_types_MlKemPublicKey_15 *public_key, - uint8_t randomness[32U]) { - uint8_t randomness0[32U]; - libcrux_ml_kem_variant_entropy_preprocess_33_8a( - Eurydice_array_to_slice((size_t)32U, randomness, uint8_t), randomness0); - uint8_t to_hash[64U]; - libcrux_ml_kem_utils_into_padded_array_ea( - Eurydice_array_to_slice((size_t)32U, randomness0, uint8_t), to_hash); - Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( - (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - size_t); - uint8_t ret[32U]; - libcrux_ml_kem_hash_functions_portable_H_f1_1a( - Eurydice_array_to_slice((size_t)1184U, - libcrux_ml_kem_types_as_slice_cb_50(public_key), - uint8_t), - ret); - Eurydice_slice_copy( - uu____0, Eurydice_array_to_slice((size_t)32U, ret, uint8_t), uint8_t); +static KRML_MUSTINLINE tuple_c2 libcrux_ml_kem_ind_cca_unpacked_encapsulate_0c( + libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0 *public_key, + uint8_t *randomness) { uint8_t hashed[64U]; - libcrux_ml_kem_hash_functions_portable_G_f1_e4( - Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t), hashed); - Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( + libcrux_ml_kem_ind_cca_unpacked_encaps_prepare_9c( + Eurydice_array_to_slice((size_t)32U, randomness, uint8_t), + Eurydice_array_to_slice((size_t)32U, public_key->public_key_hash, + uint8_t), + hashed); + Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at( Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice shared_secret = uu____1.fst; - Eurydice_slice pseudorandomness = uu____1.snd; - Eurydice_slice uu____2 = Eurydice_array_to_slice( - (size_t)1184U, libcrux_ml_kem_types_as_slice_cb_50(public_key), uint8_t); - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_randomness[32U]; - memcpy(copy_of_randomness, randomness0, (size_t)32U * sizeof(uint8_t)); + Eurydice_slice shared_secret = uu____0.fst; + Eurydice_slice pseudorandomness = uu____0.snd; uint8_t ciphertext[1088U]; - libcrux_ml_kem_ind_cpa_encrypt_60(uu____2, copy_of_randomness, - pseudorandomness, ciphertext); + libcrux_ml_kem_ind_cpa_encrypt_unpacked_2a(&public_key->ind_cpa_public_key, + randomness, pseudorandomness, + ciphertext); + uint8_t shared_secret_array[32U] = {0U}; + Eurydice_slice_copy( + Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t), + shared_secret, uint8_t); /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_ciphertext[1088U]; memcpy(copy_of_ciphertext, ciphertext, (size_t)1088U * sizeof(uint8_t)); - libcrux_ml_kem_mlkem768_MlKem768Ciphertext ciphertext0 = - libcrux_ml_kem_types_from_01_9f(copy_of_ciphertext); - uint8_t shared_secret_array[32U]; - libcrux_ml_kem_variant_kdf_33_f0(shared_secret, &ciphertext0, - shared_secret_array); - libcrux_ml_kem_mlkem768_MlKem768Ciphertext uu____5 = ciphertext0; + libcrux_ml_kem_mlkem768_MlKem768Ciphertext uu____2 = + libcrux_ml_kem_types_from_e0_80(copy_of_ciphertext); /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_shared_secret_array[32U]; memcpy(copy_of_shared_secret_array, shared_secret_array, (size_t)32U * sizeof(uint8_t)); - tuple_3c lit; - lit.fst = uu____5; + tuple_c2 lit; + lit.fst = uu____2; memcpy(lit.snd, copy_of_shared_secret_array, (size_t)32U * sizeof(uint8_t)); return lit; } /** - Portable encapsulate + Unpacked encapsulate */ /** A monomorphic instance of -libcrux_ml_kem.ind_cca.instantiations.portable.kyber_encapsulate with const +libcrux_ml_kem.ind_cca.instantiations.portable.unpacked.encapsulate with const generics - K= 3 - CIPHERTEXT_SIZE= 1088 @@ -11907,428 +10992,761 @@ generics - ETA2= 2 - ETA2_RANDOMNESS_SIZE= 128 */ -static inline tuple_3c -libcrux_ml_kem_ind_cca_instantiations_portable_kyber_encapsulate_7a( - libcrux_ml_kem_types_MlKemPublicKey_15 *public_key, +static KRML_MUSTINLINE tuple_c2 +libcrux_ml_kem_ind_cca_instantiations_portable_unpacked_encapsulate_cd( + libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0 *public_key, + uint8_t *randomness) { + return libcrux_ml_kem_ind_cca_unpacked_encapsulate_0c(public_key, randomness); +} + +/** + Encapsulate ML-KEM 768 (unpacked) + + Generates an ([`MlKem768Ciphertext`], [`MlKemSharedSecret`]) tuple. + The input is a reference to an unpacked public key of type + [`MlKem768PublicKeyUnpacked`], the SHA3-256 hash of this public key, and + [`SHARED_SECRET_SIZE`] bytes of `randomness`. +*/ +static inline tuple_c2 libcrux_ml_kem_mlkem768_portable_unpacked_encapsulate( + libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0 *public_key, uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey_15 *uu____0 = public_key; + return libcrux_ml_kem_ind_cca_instantiations_portable_unpacked_encapsulate_cd( + public_key, randomness); +} + +/** +This function found in impl {core::ops::function::FnMut<(usize), +libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0, +TraitClause@1]> for +libcrux_ml_kem::ind_cca::unpacked::transpose_a::closure::closure[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.unpacked.transpose_a.closure.call_mut_b4 with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- K= 3 +*/ +static inline libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_ind_cca_unpacked_transpose_a_closure_call_mut_b4_1b( + void **_, size_t tupled_args) { + return libcrux_ml_kem_polynomial_ZERO_d6_ea(); +} + +/** +This function found in impl {core::ops::function::FnMut<(usize), +@Array[TraitClause@0, +TraitClause@1], K>> for +libcrux_ml_kem::ind_cca::unpacked::transpose_a::closure[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.unpacked.transpose_a.call_mut_7b with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- K= 3 +*/ +static inline void libcrux_ml_kem_ind_cca_unpacked_transpose_a_call_mut_7b_1b( + void **_, size_t tupled_args, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d ret[3U]) { + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + /* original Rust expression is not an lvalue in C */ + void *lvalue = (void *)0U; + ret[i] = libcrux_ml_kem_ind_cca_unpacked_transpose_a_closure_call_mut_b4_1b( + &lvalue, i); + } +} + +/** +This function found in impl {core::clone::Clone for +libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0, +TraitClause@2]} +*/ +/** +A monomorphic instance of libcrux_ml_kem.polynomial.clone_c1 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static inline libcrux_ml_kem_polynomial_PolynomialRingElement_1d +libcrux_ml_kem_polynomial_clone_c1_ea( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d *self) { + libcrux_ml_kem_polynomial_PolynomialRingElement_1d lit; + libcrux_ml_kem_vector_portable_vector_type_PortableVector ret[16U]; + core_array__core__clone__Clone_for__Array_T__N___clone( + (size_t)16U, self->coefficients, ret, + libcrux_ml_kem_vector_portable_vector_type_PortableVector, void *); + memcpy(lit.coefficients, ret, + (size_t)16U * + sizeof(libcrux_ml_kem_vector_portable_vector_type_PortableVector)); + return lit; +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.unpacked.transpose_a +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +*/ +static inline void libcrux_ml_kem_ind_cca_unpacked_transpose_a_1b( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d ind_cpa_a[3U][3U], + libcrux_ml_kem_polynomial_PolynomialRingElement_1d ret[3U][3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement_1d A[3U][3U]; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + /* original Rust expression is not an lvalue in C */ + void *lvalue = (void *)0U; + libcrux_ml_kem_ind_cca_unpacked_transpose_a_call_mut_7b_1b(&lvalue, i, + A[i]); + } + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement_1d _a_i[3U][3U]; + memcpy(_a_i, A, + (size_t)3U * + sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d[3U])); + for (size_t i1 = (size_t)0U; i1 < (size_t)3U; i1++) { + size_t j = i1; + libcrux_ml_kem_polynomial_PolynomialRingElement_1d uu____0 = + libcrux_ml_kem_polynomial_clone_c1_ea(&ind_cpa_a[j][i0]); + A[i0][j] = uu____0; + } + } + memcpy(ret, A, + (size_t)3U * + sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d[3U])); +} + +/** + Generate Unpacked Keys +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.unpacked.generate_keypair +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]], +libcrux_ml_kem_variant_MlKem with const generics +- K= 3 +- CPA_PRIVATE_KEY_SIZE= 1152 +- PRIVATE_KEY_SIZE= 2400 +- PUBLIC_KEY_SIZE= 1184 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_unpacked_generate_keypair_15( + uint8_t randomness[64U], + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked *out) { + Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice3( + randomness, (size_t)0U, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t *); + Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( + (size_t)64U, randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, + size_t, uint8_t[]); + libcrux_ml_kem_ind_cpa_generate_keypair_unpacked_1c( + ind_cpa_keypair_randomness, &out->private_key.ind_cpa_private_key, + &out->public_key.ind_cpa_public_key); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d uu____0[3U][3U]; + memcpy(uu____0, out->public_key.ind_cpa_public_key.A, + (size_t)3U * + sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d[3U])); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d A[3U][3U]; + libcrux_ml_kem_ind_cca_unpacked_transpose_a_1b(uu____0, A); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d uu____1[3U][3U]; + memcpy(uu____1, A, + (size_t)3U * + sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d[3U])); + memcpy(out->public_key.ind_cpa_public_key.A, uu____1, + (size_t)3U * + sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d[3U])); + uint8_t pk_serialized[1184U]; + libcrux_ml_kem_ind_cpa_serialize_public_key_89( + out->public_key.ind_cpa_public_key.t_as_ntt, + Eurydice_array_to_slice( + (size_t)32U, out->public_key.ind_cpa_public_key.seed_for_A, uint8_t), + pk_serialized); + uint8_t uu____2[32U]; + libcrux_ml_kem_hash_functions_portable_H_4a_e0( + Eurydice_array_to_slice((size_t)1184U, pk_serialized, uint8_t), uu____2); + memcpy(out->public_key.public_key_hash, uu____2, + (size_t)32U * sizeof(uint8_t)); + uint8_t uu____3[32U]; + Result_fb dst; + Eurydice_slice_to_array2(&dst, implicit_rejection_value, Eurydice_slice, + uint8_t[32U], TryFromSliceError); + unwrap_26_b3(dst, uu____3); + memcpy(out->private_key.implicit_rejection_value, uu____3, + (size_t)32U * sizeof(uint8_t)); +} + +/** + Generate a key pair +*/ +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.instantiations.portable.unpacked.generate_keypair with +const generics +- K= 3 +- CPA_PRIVATE_KEY_SIZE= 1152 +- PRIVATE_KEY_SIZE= 2400 +- PUBLIC_KEY_SIZE= 1184 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_ind_cca_instantiations_portable_unpacked_generate_keypair_ce( + uint8_t randomness[64U], + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked *out) { /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_randomness[32U]; - memcpy(copy_of_randomness, randomness, (size_t)32U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_encapsulate_cd0(uu____0, copy_of_randomness); + uint8_t copy_of_randomness[64U]; + memcpy(copy_of_randomness, randomness, (size_t)64U * sizeof(uint8_t)); + libcrux_ml_kem_ind_cca_unpacked_generate_keypair_15(copy_of_randomness, out); } /** - Encapsulate Kyber 768 + Generate ML-KEM 768 Key Pair in "unpacked" form. +*/ +static inline void +libcrux_ml_kem_mlkem768_portable_unpacked_generate_key_pair_mut( + uint8_t randomness[64U], + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked + *key_pair) { + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_randomness[64U]; + memcpy(copy_of_randomness, randomness, (size_t)64U * sizeof(uint8_t)); + libcrux_ml_kem_ind_cca_instantiations_portable_unpacked_generate_keypair_ce( + copy_of_randomness, key_pair); +} - Generates an ([`MlKem768Ciphertext`], [`MlKemSharedSecret`]) tuple. - The input is a reference to an [`MlKem768PublicKey`] and [`SHARED_SECRET_SIZE`] - bytes of `randomness`. +/** +This function found in impl {core::default::Default for +libcrux_ml_kem::ind_cca::unpacked::MlKemPublicKeyUnpacked[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.unpacked.default_30 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0 +libcrux_ml_kem_ind_cca_unpacked_default_30_1b(void) { + return ( + KRML_CLITERAL(libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0){ + .ind_cpa_public_key = libcrux_ml_kem_ind_cpa_unpacked_default_8b_1b(), + .public_key_hash = {0U}}); +} + +/** +This function found in impl {core::default::Default for +libcrux_ml_kem::ind_cca::unpacked::MlKemKeyPairUnpacked[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.unpacked.default_7b +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +*/ +static KRML_MUSTINLINE + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked + libcrux_ml_kem_ind_cca_unpacked_default_7b_1b(void) { + libcrux_ml_kem_ind_cca_unpacked_MlKemPrivateKeyUnpacked_a0 uu____0 = { + .ind_cpa_private_key = libcrux_ml_kem_ind_cpa_unpacked_default_70_1b(), + .implicit_rejection_value = {0U}}; + return (KRML_CLITERAL( + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked){ + .private_key = uu____0, + .public_key = libcrux_ml_kem_ind_cca_unpacked_default_30_1b()}); +} + +/** + Generate ML-KEM 768 Key Pair in "unpacked" form. +*/ +static inline libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked +libcrux_ml_kem_mlkem768_portable_unpacked_generate_key_pair( + uint8_t randomness[64U]) { + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked key_pair = + libcrux_ml_kem_ind_cca_unpacked_default_7b_1b(); + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + libcrux_ml_kem_mlkem768_portable_unpacked_generate_key_pair_mut(uu____0, + &key_pair); + return key_pair; +} + +/** + Create a new, empty unpacked key. +*/ +static inline libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked +libcrux_ml_kem_mlkem768_portable_unpacked_init_key_pair(void) { + return libcrux_ml_kem_ind_cca_unpacked_default_7b_1b(); +} + +/** + Create a new, empty unpacked public key. +*/ +static inline libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0 +libcrux_ml_kem_mlkem768_portable_unpacked_init_public_key(void) { + return libcrux_ml_kem_ind_cca_unpacked_default_30_1b(); +} + +/** + Take a serialized private key and generate an unpacked key pair from it. +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.unpacked.keys_from_private_key +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +- SECRET_KEY_SIZE= 2400 +- CPA_SECRET_KEY_SIZE= 1152 +- PUBLIC_KEY_SIZE= 1184 +- T_AS_NTT_ENCODED_SIZE= 1152 */ -static inline tuple_3c libcrux_ml_kem_mlkem768_portable_kyber_encapsulate( - libcrux_ml_kem_types_MlKemPublicKey_15 *public_key, - uint8_t randomness[32U]) { - libcrux_ml_kem_types_MlKemPublicKey_15 *uu____0 = public_key; - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_randomness[32U]; - memcpy(copy_of_randomness, randomness, (size_t)32U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_instantiations_portable_kyber_encapsulate_7a( - uu____0, copy_of_randomness); +static KRML_MUSTINLINE void +libcrux_ml_kem_ind_cca_unpacked_keys_from_private_key_42( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked + *key_pair) { + Eurydice_slice_uint8_t_x4 uu____0 = + libcrux_ml_kem_types_unpack_private_key_b4( + Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t)); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice ind_cpa_public_key = uu____0.snd; + Eurydice_slice ind_cpa_public_key_hash = uu____0.thd; + Eurydice_slice implicit_rejection_value = uu____0.f3; + libcrux_ml_kem_ind_cpa_deserialize_vector_1b( + ind_cpa_secret_key, + key_pair->private_key.ind_cpa_private_key.secret_as_ntt); + libcrux_ml_kem_ind_cpa_build_unpacked_public_key_mut_3f( + ind_cpa_public_key, &key_pair->public_key.ind_cpa_public_key); + Eurydice_slice_copy( + Eurydice_array_to_slice((size_t)32U, key_pair->public_key.public_key_hash, + uint8_t), + ind_cpa_public_key_hash, uint8_t); + Eurydice_slice_copy( + Eurydice_array_to_slice( + (size_t)32U, key_pair->private_key.implicit_rejection_value, uint8_t), + implicit_rejection_value, uint8_t); + Eurydice_slice_copy( + Eurydice_array_to_slice( + (size_t)32U, key_pair->public_key.ind_cpa_public_key.seed_for_A, + uint8_t), + Eurydice_slice_subslice_from(ind_cpa_public_key, (size_t)1152U, uint8_t, + size_t, uint8_t[]), + uint8_t); } /** -This function found in impl {(libcrux_ml_kem::variant::Variant for -libcrux_ml_kem::variant::Kyber)} + Take a serialized private key and generate an unpacked key pair from it. */ /** -A monomorphic instance of libcrux_ml_kem.variant.cpa_keygen_seed_33 -with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] +A monomorphic instance of +libcrux_ml_kem.ind_cca.instantiations.portable.unpacked.keypair_from_private_key with const generics - K= 3 +- SECRET_KEY_SIZE= 2400 +- CPA_SECRET_KEY_SIZE= 1152 +- PUBLIC_KEY_SIZE= 1184 +- T_AS_NTT_ENCODED_SIZE= 1152 */ -static KRML_MUSTINLINE void libcrux_ml_kem_variant_cpa_keygen_seed_33_b6( - Eurydice_slice key_generation_seed, uint8_t ret[64U]) { - libcrux_ml_kem_hash_functions_portable_G_f1_e4(key_generation_seed, ret); +static KRML_MUSTINLINE void +libcrux_ml_kem_ind_cca_instantiations_portable_unpacked_keypair_from_private_key_fd( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked + *key_pair) { + libcrux_ml_kem_ind_cca_unpacked_keys_from_private_key_42(private_key, + key_pair); } /** -A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair -with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, -libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]], -libcrux_ml_kem_variant_Kyber with const generics -- K= 3 -- PRIVATE_KEY_SIZE= 1152 -- PUBLIC_KEY_SIZE= 1184 -- RANKED_BYTES_PER_RING_ELEMENT= 1152 -- ETA1= 2 -- ETA1_RANDOMNESS_SIZE= 128 + Get an unpacked key from a private key. */ -static inline libcrux_ml_kem_utils_extraction_helper_Keypair768 -libcrux_ml_kem_ind_cpa_generate_keypair_fc0( - Eurydice_slice key_generation_seed) { - uint8_t hashed[64U]; - libcrux_ml_kem_variant_cpa_keygen_seed_33_b6(key_generation_seed, hashed); - Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at( - Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), (size_t)32U, - uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice seed_for_A0 = uu____0.fst; - Eurydice_slice seed_for_secret_and_error = uu____0.snd; - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 A_transpose[3U][3U]; - uint8_t ret[34U]; - libcrux_ml_kem_utils_into_padded_array_ea1(seed_for_A0, ret); - libcrux_ml_kem_matrix_sample_matrix_A_38(ret, true, A_transpose); - uint8_t prf_input[33U]; - libcrux_ml_kem_utils_into_padded_array_ea2(seed_for_secret_and_error, - prf_input); - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_prf_input0[33U]; - memcpy(copy_of_prf_input0, prf_input, (size_t)33U * sizeof(uint8_t)); - tuple_b0 uu____2 = libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_fc( - copy_of_prf_input0, 0U); - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 secret_as_ntt[3U]; - memcpy( - secret_as_ntt, uu____2.fst, - (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); - uint8_t domain_separator = uu____2.snd; - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_prf_input[33U]; - memcpy(copy_of_prf_input, prf_input, (size_t)33U * sizeof(uint8_t)); - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 error_as_ntt[3U]; - memcpy( - error_as_ntt, - libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_fc(copy_of_prf_input, - domain_separator) - .fst, - (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 t_as_ntt[3U]; - libcrux_ml_kem_matrix_compute_As_plus_e_60(A_transpose, secret_as_ntt, - error_as_ntt, t_as_ntt); - uint8_t seed_for_A[32U]; - Result_00 dst; - Eurydice_slice_to_array2(&dst, seed_for_A0, Eurydice_slice, uint8_t[32U]); - unwrap_41_83(dst, seed_for_A); - uint8_t public_key_serialized[1184U]; - libcrux_ml_kem_ind_cpa_serialize_public_key_79( - t_as_ntt, Eurydice_array_to_slice((size_t)32U, seed_for_A, uint8_t), - public_key_serialized); - uint8_t secret_key_serialized[1152U]; - libcrux_ml_kem_ind_cpa_serialize_secret_key_b5(secret_as_ntt, - secret_key_serialized); - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_secret_key_serialized[1152U]; - memcpy(copy_of_secret_key_serialized, secret_key_serialized, - (size_t)1152U * sizeof(uint8_t)); - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_public_key_serialized[1184U]; - memcpy(copy_of_public_key_serialized, public_key_serialized, - (size_t)1184U * sizeof(uint8_t)); - libcrux_ml_kem_utils_extraction_helper_Keypair768 lit; - memcpy(lit.fst, copy_of_secret_key_serialized, - (size_t)1152U * sizeof(uint8_t)); - memcpy(lit.snd, copy_of_public_key_serialized, - (size_t)1184U * sizeof(uint8_t)); - return lit; +static inline void +libcrux_ml_kem_mlkem768_portable_unpacked_key_pair_from_private_mut( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked + *key_pair) { + libcrux_ml_kem_ind_cca_instantiations_portable_unpacked_keypair_from_private_key_fd( + private_key, key_pair); } /** - Packed API - - Generate a key pair. - - Depending on the `Vector` and `Hasher` used, this requires different hardware - features +This function found in impl +{libcrux_ml_kem::ind_cca::unpacked::MlKemKeyPairUnpacked[TraitClause@0, TraitClause@1]} */ /** -A monomorphic instance of libcrux_ml_kem.ind_cca.generate_keypair -with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, -libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]], -libcrux_ml_kem_variant_Kyber with const generics +A monomorphic instance of +libcrux_ml_kem.ind_cca.unpacked.serialized_private_key_mut_11 with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics - K= 3 - CPA_PRIVATE_KEY_SIZE= 1152 - PRIVATE_KEY_SIZE= 2400 - PUBLIC_KEY_SIZE= 1184 -- BYTES_PER_RING_ELEMENT= 1152 -- ETA1= 2 -- ETA1_RANDOMNESS_SIZE= 128 */ -static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair -libcrux_ml_kem_ind_cca_generate_keypair_8c0(uint8_t randomness[64U]) { - Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice2( - randomness, (size_t)0U, - LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t); - Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( - (size_t)64U, randomness, - LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, - size_t); +static KRML_MUSTINLINE void +libcrux_ml_kem_ind_cca_unpacked_serialized_private_key_mut_11_43( + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked *self, + libcrux_ml_kem_types_MlKemPrivateKey_d9 *serialized) { libcrux_ml_kem_utils_extraction_helper_Keypair768 uu____0 = - libcrux_ml_kem_ind_cpa_generate_keypair_fc0(ind_cpa_keypair_randomness); + libcrux_ml_kem_ind_cpa_serialize_unpacked_secret_key_6c( + &self->public_key.ind_cpa_public_key, + &self->private_key.ind_cpa_private_key); uint8_t ind_cpa_private_key[1152U]; memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof(uint8_t)); - uint8_t public_key[1184U]; - memcpy(public_key, uu____0.snd, (size_t)1184U * sizeof(uint8_t)); - uint8_t secret_key_serialized[2400U]; - libcrux_ml_kem_ind_cca_serialize_kem_secret_key_48( + uint8_t ind_cpa_public_key[1184U]; + memcpy(ind_cpa_public_key, uu____0.snd, (size_t)1184U * sizeof(uint8_t)); + libcrux_ml_kem_ind_cca_serialize_kem_secret_key_mut_d6( Eurydice_array_to_slice((size_t)1152U, ind_cpa_private_key, uint8_t), - Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t), - implicit_rejection_value, secret_key_serialized); - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_secret_key_serialized[2400U]; - memcpy(copy_of_secret_key_serialized, secret_key_serialized, - (size_t)2400U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPrivateKey_55 private_key = - libcrux_ml_kem_types_from_05_f2(copy_of_secret_key_serialized); - libcrux_ml_kem_types_MlKemPrivateKey_55 uu____2 = private_key; - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_public_key[1184U]; - memcpy(copy_of_public_key, public_key, (size_t)1184U * sizeof(uint8_t)); - return libcrux_ml_kem_types_from_17_35( - uu____2, libcrux_ml_kem_types_from_b6_da(copy_of_public_key)); + Eurydice_array_to_slice((size_t)1184U, ind_cpa_public_key, uint8_t), + Eurydice_array_to_slice( + (size_t)32U, self->private_key.implicit_rejection_value, uint8_t), + serialized->value); } +/** +This function found in impl +{libcrux_ml_kem::ind_cca::unpacked::MlKemKeyPairUnpacked[TraitClause@0, TraitClause@1]} +*/ /** A monomorphic instance of -libcrux_ml_kem.ind_cca.instantiations.portable.kyber_generate_keypair with const -generics +libcrux_ml_kem.ind_cca.unpacked.serialized_private_key_11 with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics - K= 3 - CPA_PRIVATE_KEY_SIZE= 1152 - PRIVATE_KEY_SIZE= 2400 - PUBLIC_KEY_SIZE= 1184 -- BYTES_PER_RING_ELEMENT= 1152 -- ETA1= 2 -- ETA1_RANDOMNESS_SIZE= 128 */ -static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair -libcrux_ml_kem_ind_cca_instantiations_portable_kyber_generate_keypair_9b( - uint8_t randomness[64U]) { - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_randomness[64U]; - memcpy(copy_of_randomness, randomness, (size_t)64U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_generate_keypair_8c0(copy_of_randomness); +static KRML_MUSTINLINE libcrux_ml_kem_types_MlKemPrivateKey_d9 +libcrux_ml_kem_ind_cca_unpacked_serialized_private_key_11_43( + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked *self) { + libcrux_ml_kem_types_MlKemPrivateKey_d9 sk = + libcrux_ml_kem_types_default_d3_28(); + libcrux_ml_kem_ind_cca_unpacked_serialized_private_key_mut_11_43(self, &sk); + return sk; } /** - Generate Kyber 768 Key Pair + Get the serialized private key. */ -static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair -libcrux_ml_kem_mlkem768_portable_kyber_generate_key_pair( - uint8_t randomness[64U]) { - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_randomness[64U]; - memcpy(copy_of_randomness, randomness, (size_t)64U * sizeof(uint8_t)); - return libcrux_ml_kem_ind_cca_instantiations_portable_kyber_generate_keypair_9b( - copy_of_randomness); +static inline libcrux_ml_kem_types_MlKemPrivateKey_d9 +libcrux_ml_kem_mlkem768_portable_unpacked_key_pair_serialized_private_key( + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked + *key_pair) { + return libcrux_ml_kem_ind_cca_unpacked_serialized_private_key_11_43(key_pair); } /** - Validate an ML-KEM private key. + Get the serialized private key. +*/ +static inline void +libcrux_ml_kem_mlkem768_portable_unpacked_key_pair_serialized_private_key_mut( + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked *key_pair, + libcrux_ml_kem_types_MlKemPrivateKey_d9 *serialized) { + libcrux_ml_kem_ind_cca_unpacked_serialized_private_key_mut_11_43(key_pair, + serialized); +} - This implements the Hash check in 7.3 3. - Note that the size checks in 7.2 1 and 2 are covered by the `SECRET_KEY_SIZE` - and `CIPHERTEXT_SIZE` in the `private_key` and `ciphertext` types. +/** +This function found in impl +{libcrux_ml_kem::ind_cca::unpacked::MlKemPublicKeyUnpacked[TraitClause@0, TraitClause@1]} */ /** -A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key -with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] +A monomorphic instance of libcrux_ml_kem.ind_cca.unpacked.serialized_dd +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics - K= 3 -- SECRET_KEY_SIZE= 2400 -- CIPHERTEXT_SIZE= 1088 +- PUBLIC_KEY_SIZE= 1184 */ -static KRML_MUSTINLINE bool libcrux_ml_kem_ind_cca_validate_private_key_e7( - libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key, - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *_ciphertext) { - uint8_t t[32U]; - libcrux_ml_kem_hash_functions_portable_H_f1_1a( - Eurydice_array_to_subslice2(private_key->value, (size_t)384U * (size_t)3U, - (size_t)768U * (size_t)3U + (size_t)32U, - uint8_t), - t); - Eurydice_slice expected = Eurydice_array_to_subslice2( - private_key->value, (size_t)768U * (size_t)3U + (size_t)32U, - (size_t)768U * (size_t)3U + (size_t)64U, uint8_t); - return core_array_equality___core__cmp__PartialEq__0___Slice_U____for__Array_T__N___3__eq( - (size_t)32U, t, &expected, uint8_t, uint8_t, bool); +static KRML_MUSTINLINE libcrux_ml_kem_types_MlKemPublicKey_30 +libcrux_ml_kem_ind_cca_unpacked_serialized_dd_89( + libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0 *self) { + uint8_t ret[1184U]; + libcrux_ml_kem_ind_cpa_serialize_public_key_89( + self->ind_cpa_public_key.t_as_ntt, + Eurydice_array_to_slice((size_t)32U, self->ind_cpa_public_key.seed_for_A, + uint8_t), + ret); + return libcrux_ml_kem_types_from_fd_d0(ret); } /** - Portable private key validation +This function found in impl +{libcrux_ml_kem::ind_cca::unpacked::MlKemKeyPairUnpacked[TraitClause@0, TraitClause@1]} */ /** A monomorphic instance of -libcrux_ml_kem.ind_cca.instantiations.portable.validate_private_key with const -generics +libcrux_ml_kem.ind_cca.unpacked.serialized_public_key_11 with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics - K= 3 -- SECRET_KEY_SIZE= 2400 -- CIPHERTEXT_SIZE= 1088 +- PUBLIC_KEY_SIZE= 1184 */ -static KRML_MUSTINLINE bool -libcrux_ml_kem_ind_cca_instantiations_portable_validate_private_key_9c( - libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key, - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext) { - return libcrux_ml_kem_ind_cca_validate_private_key_e7(private_key, - ciphertext); +static KRML_MUSTINLINE libcrux_ml_kem_types_MlKemPublicKey_30 +libcrux_ml_kem_ind_cca_unpacked_serialized_public_key_11_89( + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked *self) { + return libcrux_ml_kem_ind_cca_unpacked_serialized_dd_89(&self->public_key); } /** - Validate a private key. - - Returns `true` if valid, and `false` otherwise. + Get the serialized public key. */ -static inline bool libcrux_ml_kem_mlkem768_portable_validate_private_key( - libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key, - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext) { - return libcrux_ml_kem_ind_cca_instantiations_portable_validate_private_key_9c( - private_key, ciphertext); +static inline libcrux_ml_kem_types_MlKemPublicKey_30 +libcrux_ml_kem_mlkem768_portable_unpacked_key_pair_serialized_public_key( + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked + *key_pair) { + return libcrux_ml_kem_ind_cca_unpacked_serialized_public_key_11_89(key_pair); } /** -A monomorphic instance of -libcrux_ml_kem.serialize.deserialize_ring_elements_reduced.closure with types -libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics -- PUBLIC_KEY_SIZE= 1184 +This function found in impl +{libcrux_ml_kem::ind_cca::unpacked::MlKemPublicKeyUnpacked[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.unpacked.serialized_mut_dd +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics - K= 3 +- PUBLIC_KEY_SIZE= 1184 */ -static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0 -libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_closure_cd0( - size_t _i) { - return libcrux_ml_kem_polynomial_ZERO_89_ea(); +static KRML_MUSTINLINE void +libcrux_ml_kem_ind_cca_unpacked_serialized_mut_dd_89( + libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0 *self, + libcrux_ml_kem_types_MlKemPublicKey_30 *serialized) { + libcrux_ml_kem_ind_cpa_serialize_public_key_mut_89( + self->ind_cpa_public_key.t_as_ntt, + Eurydice_array_to_slice((size_t)32U, self->ind_cpa_public_key.seed_for_A, + uint8_t), + serialized->value); } /** - This function deserializes ring elements and reduces the result by the field - modulus. - - This function MUST NOT be used on secret inputs. +This function found in impl +{libcrux_ml_kem::ind_cca::unpacked::MlKemKeyPairUnpacked[TraitClause@0, TraitClause@1]} */ /** A monomorphic instance of -libcrux_ml_kem.serialize.deserialize_ring_elements_reduced with types +libcrux_ml_kem.ind_cca.unpacked.serialized_public_key_mut_11 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics -- PUBLIC_KEY_SIZE= 1184 - K= 3 +- PUBLIC_KEY_SIZE= 1184 */ static KRML_MUSTINLINE void -libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_330( - Eurydice_slice public_key, - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U]) { - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 deserialized_pk[3U]; - for (size_t i = (size_t)0U; i < (size_t)3U; i++) { - deserialized_pk[i] = libcrux_ml_kem_polynomial_ZERO_89_ea(); - } - for (size_t i = (size_t)0U; - i < Eurydice_slice_len(public_key, uint8_t) / - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; - i++) { - size_t i0 = i; - Eurydice_slice ring_element = Eurydice_slice_subslice2( - public_key, i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + - LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, - uint8_t); - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 uu____0 = - libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element_4c( - ring_element); - deserialized_pk[i0] = uu____0; - } - memcpy( - ret, deserialized_pk, - (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); +libcrux_ml_kem_ind_cca_unpacked_serialized_public_key_mut_11_89( + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked *self, + libcrux_ml_kem_types_MlKemPublicKey_30 *serialized) { + libcrux_ml_kem_ind_cca_unpacked_serialized_mut_dd_89(&self->public_key, + serialized); } /** - Validate an ML-KEM public key. + Get the serialized public key. +*/ +static inline void +libcrux_ml_kem_mlkem768_portable_unpacked_key_pair_serialized_public_key_mut( + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked *key_pair, + libcrux_ml_kem_types_MlKemPublicKey_30 *serialized) { + libcrux_ml_kem_ind_cca_unpacked_serialized_public_key_mut_11_89(key_pair, + serialized); +} - This implements the Modulus check in 7.2 2. - Note that the size check in 7.2 1 is covered by the `PUBLIC_KEY_SIZE` in the - `public_key` type. +/** +This function found in impl {core::clone::Clone for +libcrux_ml_kem::ind_cpa::unpacked::IndCpaPublicKeyUnpacked[TraitClause@0, TraitClause@2]} */ /** -A monomorphic instance of libcrux_ml_kem.ind_cca.validate_public_key +A monomorphic instance of libcrux_ml_kem.ind_cpa.unpacked.clone_91 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics - K= 3 -- RANKED_BYTES_PER_RING_ELEMENT= 1152 -- PUBLIC_KEY_SIZE= 1184 */ -static KRML_MUSTINLINE bool libcrux_ml_kem_ind_cca_validate_public_key_19( - uint8_t *public_key) { - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 deserialized_pk[3U]; - libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_330( - Eurydice_array_to_subslice_to((size_t)1184U, public_key, (size_t)1152U, - uint8_t, size_t), - deserialized_pk); - libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *uu____0 = deserialized_pk; - uint8_t public_key_serialized[1184U]; - libcrux_ml_kem_ind_cpa_serialize_public_key_79( - uu____0, - Eurydice_array_to_subslice_from((size_t)1184U, public_key, (size_t)1152U, - uint8_t, size_t), - public_key_serialized); - return core_array_equality___core__cmp__PartialEq__Array_U__N___for__Array_T__N____eq( - (size_t)1184U, public_key, public_key_serialized, uint8_t, uint8_t, bool); +static inline libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_a0 +libcrux_ml_kem_ind_cpa_unpacked_clone_91_1b( + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_a0 *self) { + libcrux_ml_kem_polynomial_PolynomialRingElement_1d uu____0[3U]; + core_array__core__clone__Clone_for__Array_T__N___clone( + (size_t)3U, self->t_as_ntt, uu____0, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d, void *); + uint8_t uu____1[32U]; + core_array__core__clone__Clone_for__Array_T__N___clone( + (size_t)32U, self->seed_for_A, uu____1, uint8_t, void *); + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_a0 lit; + memcpy( + lit.t_as_ntt, uu____0, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); + memcpy(lit.seed_for_A, uu____1, (size_t)32U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d ret[3U][3U]; + core_array__core__clone__Clone_for__Array_T__N___clone( + (size_t)3U, self->A, ret, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d[3U], void *); + memcpy(lit.A, ret, + (size_t)3U * + sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d[3U])); + return lit; } /** - Portable public key validation +This function found in impl {core::clone::Clone for +libcrux_ml_kem::ind_cca::unpacked::MlKemPublicKeyUnpacked[TraitClause@0, TraitClause@2]} */ /** -A monomorphic instance of -libcrux_ml_kem.ind_cca.instantiations.portable.validate_public_key with const -generics +A monomorphic instance of libcrux_ml_kem.ind_cca.unpacked.clone_d7 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics - K= 3 -- RANKED_BYTES_PER_RING_ELEMENT= 1152 -- PUBLIC_KEY_SIZE= 1184 */ -static KRML_MUSTINLINE bool -libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key_4b( - uint8_t *public_key) { - return libcrux_ml_kem_ind_cca_validate_public_key_19(public_key); +static inline libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0 +libcrux_ml_kem_ind_cca_unpacked_clone_d7_1b( + libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0 *self) { + libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0 lit; + lit.ind_cpa_public_key = + libcrux_ml_kem_ind_cpa_unpacked_clone_91_1b(&self->ind_cpa_public_key); + uint8_t ret[32U]; + core_array__core__clone__Clone_for__Array_T__N___clone( + (size_t)32U, self->public_key_hash, ret, uint8_t, void *); + memcpy(lit.public_key_hash, ret, (size_t)32U * sizeof(uint8_t)); + return lit; } /** - Validate a public key. +This function found in impl +{libcrux_ml_kem::ind_cca::unpacked::MlKemKeyPairUnpacked[TraitClause@0, TraitClause@1]} +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.unpacked.public_key_11 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0 * +libcrux_ml_kem_ind_cca_unpacked_public_key_11_1b( + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked *self) { + return &self->public_key; +} - Returns `true` if valid, and `false` otherwise. +/** + Get the unpacked public key. */ -static inline bool libcrux_ml_kem_mlkem768_portable_validate_public_key( - libcrux_ml_kem_types_MlKemPublicKey_15 *public_key) { - return libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key_4b( - public_key->value); +static inline void libcrux_ml_kem_mlkem768_portable_unpacked_public_key( + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked *key_pair, + libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0 *pk) { + libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0 uu____0 = + libcrux_ml_kem_ind_cca_unpacked_clone_d7_1b( + libcrux_ml_kem_ind_cca_unpacked_public_key_11_1b(key_pair)); + pk[0U] = uu____0; } /** -This function found in impl {(core::clone::Clone for -libcrux_ml_kem::vector::portable::vector_type::PortableVector)} + Get the serialized public key. */ -static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector -libcrux_ml_kem_vector_portable_vector_type_clone_3b( - libcrux_ml_kem_vector_portable_vector_type_PortableVector *self) { - return self[0U]; +static inline void +libcrux_ml_kem_mlkem768_portable_unpacked_serialized_public_key( + libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0 *public_key, + libcrux_ml_kem_types_MlKemPublicKey_30 *serialized) { + libcrux_ml_kem_ind_cca_unpacked_serialized_mut_dd_89(public_key, serialized); } -typedef int16_t libcrux_ml_kem_vector_portable_vector_type_FieldElement; +/** + Generate an unpacked key from a serialized key. +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.unpacked.unpack_public_key +with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]], +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- K= 3 +- T_AS_NTT_ENCODED_SIZE= 1152 +- PUBLIC_KEY_SIZE= 1184 +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_ind_cca_unpacked_unpack_public_key_0a( + libcrux_ml_kem_types_MlKemPublicKey_30 *public_key, + libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0 + *unpacked_public_key) { + Eurydice_slice uu____0 = + Eurydice_array_to_subslice_to((size_t)1184U, public_key->value, + (size_t)1152U, uint8_t, size_t, uint8_t[]); + libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_1b( + uu____0, unpacked_public_key->ind_cpa_public_key.t_as_ntt); + uint8_t uu____1[32U]; + libcrux_ml_kem_utils_into_padded_array_9e( + Eurydice_array_to_subslice_from((size_t)1184U, public_key->value, + (size_t)1152U, uint8_t, size_t, + uint8_t[]), + uu____1); + memcpy(unpacked_public_key->ind_cpa_public_key.seed_for_A, uu____1, + (size_t)32U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d(*uu____2)[3U] = + unpacked_public_key->ind_cpa_public_key.A; + uint8_t ret[34U]; + libcrux_ml_kem_utils_into_padded_array_b6( + Eurydice_array_to_subslice_from((size_t)1184U, public_key->value, + (size_t)1152U, uint8_t, size_t, + uint8_t[]), + ret); + libcrux_ml_kem_matrix_sample_matrix_A_2b(uu____2, ret, false); + uint8_t uu____3[32U]; + libcrux_ml_kem_hash_functions_portable_H_4a_e0( + Eurydice_array_to_slice((size_t)1184U, + libcrux_ml_kem_types_as_slice_e6_d0(public_key), + uint8_t), + uu____3); + memcpy(unpacked_public_key->public_key_hash, uu____3, + (size_t)32U * sizeof(uint8_t)); +} -typedef int16_t - libcrux_ml_kem_vector_portable_arithmetic_MontgomeryFieldElement; +/** + Get the unpacked public key. +*/ +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.instantiations.portable.unpacked.unpack_public_key with +const generics +- K= 3 +- T_AS_NTT_ENCODED_SIZE= 1152 +- PUBLIC_KEY_SIZE= 1184 +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_ind_cca_instantiations_portable_unpacked_unpack_public_key_31( + libcrux_ml_kem_types_MlKemPublicKey_30 *public_key, + libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0 + *unpacked_public_key) { + libcrux_ml_kem_ind_cca_unpacked_unpack_public_key_0a(public_key, + unpacked_public_key); +} -typedef int16_t - libcrux_ml_kem_vector_portable_arithmetic_FieldElementTimesMontgomeryR; +/** + Get the unpacked public key. +*/ +static inline void +libcrux_ml_kem_mlkem768_portable_unpacked_unpacked_public_key( + libcrux_ml_kem_types_MlKemPublicKey_30 *public_key, + libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0 + *unpacked_public_key) { + libcrux_ml_kem_ind_cca_instantiations_portable_unpacked_unpack_public_key_31( + public_key, unpacked_public_key); +} #if defined(__cplusplus) } #endif -#define __libcrux_mlkem768_portable_H_DEFINED -#endif +#define libcrux_mlkem768_portable_H_DEFINED +#endif /* libcrux_mlkem768_portable_H */ /* rename some types to be a bit more ergonomic */ #define libcrux_mlkem768_keypair libcrux_ml_kem_mlkem768_MlKem768KeyPair_s -#define libcrux_mlkem768_pk_valid_result Option_92_s -#define libcrux_mlkem768_pk libcrux_ml_kem_types_MlKemPublicKey_15_s -#define libcrux_mlkem768_sk libcrux_ml_kem_types_MlKemPrivateKey_55_s +#define libcrux_mlkem768_pk libcrux_ml_kem_types_MlKemPublicKey_30_s +#define libcrux_mlkem768_sk libcrux_ml_kem_types_MlKemPrivateKey_d9_s #define libcrux_mlkem768_ciphertext libcrux_ml_kem_mlkem768_MlKem768Ciphertext_s -#define libcrux_mlkem768_enc_result tuple_3c_s +#define libcrux_mlkem768_enc_result tuple_c2_s /* defines for PRNG inputs */ -#define LIBCRUX_ML_KEM_KEY_PAIR_PRNG_LEN 64 +#define LIBCRUX_ML_KEM_KEY_PAIR_PRNG_LEN 64U #define LIBCRUX_ML_KEM_ENC_PRNG_LEN 32 diff --git a/log.c b/log.c index 23ad10c..2903871 100644 --- a/log.c +++ b/log.c @@ -1,4 +1,4 @@ -/* $OpenBSD: log.c,v 1.62 2024/06/27 22:36:44 djm Exp $ */ +/* $OpenBSD: log.c,v 1.67 2026/02/14 00:18:34 jsg Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -38,14 +38,15 @@ #include +#include #include +#include #include #include #include #include #include #include -#include #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS) # include #endif @@ -62,7 +63,6 @@ static log_handler_fn *log_handler; static void *log_handler_ctx; static char **log_verbose; static size_t nlog_verbose; - extern char *__progname; #define LOG_SYSLOG_VIS (VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL) @@ -401,7 +401,8 @@ do_log(LogLevel level, int force, const char *suffix, const char *fmt, /* Avoid recursion */ tmp_handler = log_handler; log_handler = NULL; - tmp_handler(level, force, fmtbuf, log_handler_ctx); + /* Note: this sends the raw (i.e. no strnvis) log message */ + tmp_handler(level, force, msgbuf, log_handler_ctx); log_handler = tmp_handler; } else if (log_on_stderr) { snprintf(msgbuf, sizeof msgbuf, "%s%s%.*s\r\n", @@ -460,9 +461,9 @@ sshlogv(const char *file, const char *func, int line, int showfunc, if (nlog_verbose == 0 && level > log_level) return; - snprintf(tag, sizeof(tag), "%.48s:%.48s():%d (pid=%ld)", + snprintf(tag, sizeof(tag), "%.48s:%.48s():%d (bin=%s, pid=%ld)", (cp = strrchr(file, '/')) == NULL ? file : cp + 1, func, line, - (long)getpid()); + argv0 == NULL ? "UNKNOWN" : argv0, (long)getpid()); for (i = 0; i < nlog_verbose; i++) { if (match_pattern_list(tag, log_verbose[i], 0) == 1) { forced = 1; @@ -489,3 +490,167 @@ sshlogdirect(LogLevel level, int forced, const char *fmt, ...) do_log(level, forced, NULL, fmt, args); va_end(args); } + + +/* + * A simple system for ratelimiting aperiodic events such as logs, without + * needing to be hooked into a mainloop/timer. A running total of events is + * maintained and when it exceeds a threshold further events are dropped + * until the rate falls back below that threshold. + * + * To prevent flipping in and out of rate-limiting, there is a hysteresis + * timer that delays leaving the rate-limited state. + * + * While in the rate-limited state, events can be periodically allowed through + * and the number of dropped events since the last log obtained. + * + * XXX a moving average rate of events might be a better approach here rather + * than linear decay, which can suppress events for a while after large + * bursts. + */ + +/* #define RATELIMIT_DEBUG 1 */ + +#ifdef RATELIMIT_DEBUG +# define RLDBG(x) do { \ + printf("%s:%d %s: ", __FILE__, __LINE__, __func__); \ + printf x; \ + printf("\n"); \ + fflush(stdout); \ + } while (0) +#else +# define RLDBG(x) +#endif + +/* set up a ratelimit */ +void +log_ratelimit_init(struct log_ratelimit_ctx *rl, u_int threshold, + u_int max_accum, u_int hysteresis, u_int log_every) +{ + memset(rl, 0, sizeof(*rl)); + rl->threshold = threshold; + rl->max_accum = max_accum; + rl->hysteresis = hysteresis; + rl->log_every = log_every; + RLDBG(("called: rl=%p thresh=%u max=%u hys=%u log_every=%u", + rl, rl->threshold, rl->max_accum, rl->hysteresis, rl->log_every)); +} + +/* + * check whether a log event should be dropped because of rate-limiting. + * returns non-zero if the event should be dropped. If events_since_last + * is supplied then, for periodic logs, it will be set to the number of + * dropped events since the last message. + */ +int +log_ratelimit(struct log_ratelimit_ctx *rl, time_t now, int *active, + u_int *events_dropped) +{ + time_t olast_event; + + RLDBG(("called: rl=%p thresh=%u max=%u hys=%u log_every=%u " + "accum=%u since=%ld since_last=%u", rl, rl->threshold, + rl->max_accum, rl->hysteresis, + rl->log_every, rl->accumulated_events, + rl->last_event == 0 ? -1 : (long)(now - rl->last_event), + rl->ratelimited_events)); + + if (now < 0) + return 0; + if (events_dropped != NULL) + *events_dropped = 0; + if (active != NULL) + *active = rl->ratelimit_active; + + /* First, decay accumulated events */ + if (rl->last_event <= 0) + rl->last_event = now; + if (now > rl->last_event) { + uint64_t n = now - rl->last_event; + + if (n > UINT_MAX) + n = UINT_MAX; + if (rl->accumulated_events < (u_int)n) + rl->accumulated_events = 0; + else + rl->accumulated_events -= (u_int)n; + RLDBG(("decay: accum=%u", rl->accumulated_events)); + } + rl->accumulated_events++; /* add this event */ + if (rl->accumulated_events > rl->max_accum) + rl->accumulated_events = rl->max_accum; + olast_event = rl->last_event; + rl->last_event = now; + RLDBG(("check threshold: accum=%u vs thresh=%u", + rl->accumulated_events, rl->threshold)); + + /* Are we under threshold? */ + if (rl->accumulated_events < rl->threshold) { + if (!rl->ratelimit_active) + return 0; + RLDBG(("under threshold: hys=%u since_hys=%ld since_last=%ld", + rl->hysteresis, rl->hysteresis_start == 0 ? -1 : + (long)(now - rl->hysteresis_start), + olast_event == 0 ? -1 : (long)(now - olast_event))); + if (rl->hysteresis_start == 0) { + /* active, but under threshold; hysteresis */ + if (olast_event + rl->hysteresis < now) { + /* hysteresis expired before this event */ + RLDBG(("hysteresis preexpired")); + goto inactive; + } + RLDBG(("start hysteresis")); + rl->hysteresis_start = now; + } else if (rl->hysteresis_start + rl->hysteresis < now) { + /* Hysteresis period expired, transition to inactive */ + RLDBG(("complete hysteresis")); + inactive: + if (events_dropped != NULL) + *events_dropped = rl->ratelimited_events; + if (active != NULL) + *active = 0; + rl->ratelimit_active = 0; + rl->ratelimit_start = 0; + rl->last_log = 0; + rl->hysteresis_start = 0; + rl->ratelimited_events = 0; + return 0; + } + /* ratelimiting active, but in hysteresis period */ + } else if (!rl->ratelimit_active) { + /* Transition to rate-limiting */ + RLDBG(("start ratelimit")); + rl->ratelimit_active = 1; + rl->ratelimit_start = now; + rl->last_log = now; + rl->hysteresis_start = 0; + rl->ratelimited_events = 1; + if (active != NULL) + *active = 1; + return 1; + } else if (rl->hysteresis_start != 0) { + /* active and over threshold; reset hysteresis timer */ + RLDBG(("clear hysteresis")); + rl->hysteresis_start = 0; + } + + /* over threshold or in hysteresis period; log periodically */ + if (active != NULL) + *active = 1; + RLDBG(("log_every=%u since_log=%ld", rl->log_every, + (long)(now - rl->last_log))); + if (rl->log_every > 0 && now >= rl->last_log + rl->log_every) { + RLDBG(("periodic: since_last=%u", rl->ratelimited_events)); + rl->last_log = now; + if (events_dropped != NULL) { + *events_dropped = rl->ratelimited_events; + rl->ratelimited_events = 0; + } + return 0; + } + + /* drop event */ + rl->ratelimited_events++; + RLDBG(("drop: ratelimited_events=%u", rl->ratelimited_events)); + return 1; +} diff --git a/log.h b/log.h index 8fe350b..8e8dfc2 100644 --- a/log.h +++ b/log.h @@ -1,4 +1,4 @@ -/* $OpenBSD: log.h,v 1.34 2024/06/27 22:36:44 djm Exp $ */ +/* $OpenBSD: log.h,v 1.35 2024/12/07 10:05:37 djm Exp $ */ /* * Author: Tatu Ylonen @@ -81,6 +81,30 @@ void sshfatal(const char *, const char *, int, int, void sshlogdirect(LogLevel, int, const char *, ...) __attribute__((format(printf, 3, 4))); +struct log_ratelimit_ctx { + /* configuration */ + u_int threshold; /* events per second */ + u_int max_accum; /* max events to accumulate */ + u_int hysteresis; /* seconds */ + u_int log_every; /* seconds */ + + /* state */ + time_t last_event; + u_int accumulated_events; /* used for threshold comparisons */ + + /* state while actively rate-limiting */ + int ratelimit_active; + time_t ratelimit_start; + time_t last_log; + time_t hysteresis_start; + u_int ratelimited_events; +}; + +void log_ratelimit_init(struct log_ratelimit_ctx *rl, u_int threshold, + u_int max_accum, u_int hysteresis, u_int log_every); +int log_ratelimit(struct log_ratelimit_ctx *rl, time_t now, int *active, + u_int *events_dropped); + #define do_log2(level, ...) sshlog(__FILE__, __func__, __LINE__, 0, level, NULL, __VA_ARGS__) #define debug3(...) sshlog(__FILE__, __func__, __LINE__, 0, SYSLOG_LEVEL_DEBUG3, NULL, __VA_ARGS__) #define debug2(...) sshlog(__FILE__, __func__, __LINE__, 0, SYSLOG_LEVEL_DEBUG2, NULL, __VA_ARGS__) diff --git a/loginrec.c b/loginrec.c index 7b1818b..7499aa9 100644 --- a/loginrec.c +++ b/loginrec.c @@ -66,7 +66,7 @@ * code should suffice. * * Retrieving the time of last login ('lastlog') is in some ways even - * more problemmatic than login recording. Some systems provide a + * more problematic than login recording. Some systems provide a * simple table of all users which we seek based on uid and retrieve a * relatively standard structure. Others record the same information in * a directory with a separate file, and others don't record the @@ -129,18 +129,14 @@ #include #include #include -#ifdef HAVE_SYS_TIME_H -# include -#endif +#include #include #include #include #include -#ifdef HAVE_PATHS_H -# include -#endif +#include #include #include #include @@ -162,8 +158,10 @@ #include "ssherr.h" #include "misc.h" -#ifdef HAVE_UTIL_H # include + +#ifdef USE_WTMPDB +# include #endif /** @@ -186,6 +184,9 @@ int wtmp_write_entry(struct logininfo *li); int wtmpx_write_entry(struct logininfo *li); int lastlog_write_entry(struct logininfo *li); int syslogin_write_entry(struct logininfo *li); +#ifdef USE_WTMPDB +int wtmpdb_write_entry(struct logininfo *li); +#endif int getlast_entry(struct logininfo *li); int lastlog_get_entry(struct logininfo *li); @@ -446,6 +447,9 @@ login_write(struct logininfo *li) #ifdef USE_WTMPX wtmpx_write_entry(li); #endif +#ifdef USE_WTMPDB + wtmpdb_write_entry(li); +#endif #ifdef CUSTOM_SYS_AUTH_RECORD_LOGIN if (li->type == LTYPE_LOGIN && !sys_auth_record_login(li->username,li->hostname,li->line, @@ -647,6 +651,9 @@ construct_utmp(struct logininfo *li, # ifdef HAVE_TYPE_IN_UTMP /* This is done here to keep utmp constants out of struct logininfo */ switch (li->type) { + case LTYPE_FAILED: + ut->ut_type = LOGIN_PROCESS; + break; case LTYPE_LOGIN: ut->ut_type = USER_PROCESS; break; @@ -843,7 +850,7 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut) endttyent(); if (NULL == ty) { - logit("%s: tty not found", __func__); + logit_f("tty not found"); return (0); } #else /* FIXME */ @@ -857,7 +864,7 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut) pos = (off_t)tty * sizeof(struct utmp); if ((ret = lseek(fd, pos, SEEK_SET)) == -1) { - logit("%s: lseek: %s", __func__, strerror(errno)); + logit_f("lseek: %s", strerror(errno)); close(fd); return (0); } @@ -879,7 +886,7 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut) memcpy(ut->ut_host, old_ut.ut_host, sizeof(ut->ut_host)); if ((ret = lseek(fd, pos, SEEK_SET)) == -1) { - logit("%s: lseek: %s", __func__, strerror(errno)); + logit_f("lseek: %s", strerror(errno)); close(fd); return (0); } @@ -912,12 +919,12 @@ utmp_perform_login(struct logininfo *li) construct_utmp(li, &ut); # ifdef UTMP_USE_LIBRARY if (!utmp_write_library(li, &ut)) { - logit("%s: utmp_write_library() failed", __func__); + logit_f("utmp_write_library() failed"); return (0); } # else if (!utmp_write_direct(li, &ut)) { - logit("%s: utmp_write_direct() failed", __func__); + logit_f("utmp_write_direct() failed"); return (0); } # endif @@ -933,12 +940,12 @@ utmp_perform_logout(struct logininfo *li) construct_utmp(li, &ut); # ifdef UTMP_USE_LIBRARY if (!utmp_write_library(li, &ut)) { - logit("%s: utmp_write_library() failed", __func__); + logit_f("utmp_write_library() failed"); return (0); } # else if (!utmp_write_direct(li, &ut)) { - logit("%s: utmp_write_direct() failed", __func__); + logit_f("utmp_write_direct() failed"); return (0); } # endif @@ -957,7 +964,7 @@ utmp_write_entry(struct logininfo *li) return (utmp_perform_logout(li)); default: - logit("%s: invalid type field", __func__); + logit_f("invalid type field"); return (0); } } @@ -971,7 +978,7 @@ utmp_write_entry(struct logininfo *li) /* not much point if we don't want utmpx entries */ #ifdef USE_UTMPX -/* if we have the wherewithall, use pututxline etc. */ +/* if we have the wherewithal, use pututxline etc. */ # if !defined(DISABLE_PUTUTXLINE) && defined(HAVE_SETUTXENT) && \ defined(HAVE_PUTUTXLINE) # define UTMPX_USE_LIBRARY @@ -998,7 +1005,7 @@ utmpx_write_library(struct logininfo *li, struct utmpx *utx) static int utmpx_write_direct(struct logininfo *li, struct utmpx *utx) { - logit("%s: not implemented!", __func__); + logit_f("not implemented!"); return (0); } # endif /* UTMPX_USE_LIBRARY */ @@ -1011,12 +1018,12 @@ utmpx_perform_login(struct logininfo *li) construct_utmpx(li, &utx); # ifdef UTMPX_USE_LIBRARY if (!utmpx_write_library(li, &utx)) { - logit("%s: utmp_write_library() failed", __func__); + logit_f("utmp_write_library() failed"); return (0); } # else - if (!utmpx_write_direct(li, &ut)) { - logit("%s: utmp_write_direct() failed", __func__); + if (!utmpx_write_direct(li, &utx)) { + logit_f("utmp_write_direct() failed"); return (0); } # endif @@ -1054,7 +1061,7 @@ utmpx_write_entry(struct logininfo *li) case LTYPE_LOGOUT: return (utmpx_perform_logout(li)); default: - logit("%s: invalid type field", __func__); + logit_f("invalid type field"); return (0); } } @@ -1122,7 +1129,7 @@ wtmp_write_entry(struct logininfo *li) case LTYPE_LOGOUT: return (wtmp_perform_logout(li)); default: - logit("%s: invalid type field", __func__); + logit_f("invalid type field"); return (0); } } @@ -1301,7 +1308,7 @@ wtmpx_write_entry(struct logininfo *li) case LTYPE_LOGOUT: return (wtmpx_perform_logout(li)); default: - logit("%s: invalid type field", __func__); + logit_f("invalid type field"); return (0); } } @@ -1391,6 +1398,64 @@ wtmpx_get_entry(struct logininfo *li) } #endif /* USE_WTMPX */ +#ifdef USE_WTMPDB +static int +wtmpdb_perform_login(struct logininfo *li) +{ + uint64_t login_time = li->tv_sec * ((uint64_t) 1000000ULL) + + li->tv_usec; + const char *tty; + + if (strncmp(li->line, "/dev/", 5) == 0) + tty = &(li->line[5]); + else + tty = li->line; + + li->wtmpdb_id = wtmpdb_login(NULL, USER_PROCESS, li->username, + login_time, tty, li->hostname, 0, 0); + + if (li->wtmpdb_id < 0) + return (0); + + return (1); +} + +static int +wtmpdb_perform_logout(struct logininfo *li) +{ + uint64_t logout_time = li->tv_sec * ((uint64_t) 1000000ULL) + + li->tv_usec; + + if (li->wtmpdb_id == 0) { + const char *tty; + + if (strncmp(li->line, "/dev/", 5) == 0) + tty = &(li->line[5]); + else + tty = li->line; + + li->wtmpdb_id = wtmpdb_get_id(NULL, tty, NULL); + } + wtmpdb_logout(NULL, li->wtmpdb_id, logout_time, NULL); + + return (1); +} + +int +wtmpdb_write_entry(struct logininfo *li) +{ + switch(li->type) { + case LTYPE_LOGIN: + return (wtmpdb_perform_login(li)); + case LTYPE_LOGOUT: + return (wtmpdb_perform_logout(li)); + default: + logit_f("invalid type field"); + return (0); + } +} +#endif + /** ** Low-level libutil login() functions **/ @@ -1418,7 +1483,7 @@ syslogin_perform_logout(struct logininfo *li) (void)line_stripname(line, li->line, sizeof(line)); if (!logout(line)) - logit("%s: logout() returned an error", __func__); + logit_f("logout() returned an error"); # ifdef HAVE_LOGWTMP else logwtmp(line, "", ""); @@ -1440,7 +1505,7 @@ syslogin_write_entry(struct logininfo *li) case LTYPE_LOGOUT: return (syslogin_perform_logout(li)); default: - logit("%s: Invalid type field", __func__); + logit_f("Invalid type field"); return (0); } } @@ -1529,10 +1594,10 @@ lastlog_write_entry(struct logininfo *li) strlcpy(last.ll_host, li->hostname, MIN_SIZEOF(last.ll_host, li->hostname)); last.ll_time = li->tv_sec; - + if (!lastlog_openseek(li, &fd, O_RDWR|O_CREAT)) return (0); - + /* write the entry */ if (atomicio(vwrite, fd, &last, sizeof(last)) != sizeof(last)) { close(fd); @@ -1540,11 +1605,11 @@ lastlog_write_entry(struct logininfo *li) LASTLOG_FILE, strerror(errno)); return (0); } - + close(fd); return (1); default: - logit("%s: Invalid type field", __func__); + logit_f("Invalid type field"); return (0); } } @@ -1636,7 +1701,7 @@ utmpx_get_entry(struct logininfo *li) /* * Logs failed login attempts in _PATH_BTMP if that exists. * The most common login failure is to give password instead of username. - * So the _PATH_BTMP file checked for the correct permission, so that only + * So the _PATH_BTMP file is checked for the correct permission, so that only * root can read it. */ void @@ -1670,7 +1735,7 @@ record_failed_login(struct ssh *ssh, const char *username, const char *hostname, /* Construct a logininfo and turn it into a utmp */ memset(&li, 0, sizeof(li)); - li.type = LTYPE_LOGIN; + li.type = LTYPE_FAILED; li.pid = getpid(); strlcpy(li.line, "ssh:notty", sizeof(li.line)); strlcpy(li.username, username, sizeof(li.username)); diff --git a/loginrec.h b/loginrec.h index 02bceb6..42b45f0 100644 --- a/loginrec.h +++ b/loginrec.h @@ -52,6 +52,7 @@ union login_netinfo { */ /* types - different to utmp.h 'type' macros */ /* (though set to the same value as linux, openbsd and others...) */ +#define LTYPE_FAILED 6 #define LTYPE_LOGIN 7 #define LTYPE_LOGOUT 8 @@ -79,6 +80,9 @@ struct logininfo { unsigned int tv_sec; unsigned int tv_usec; union login_netinfo hostaddr; /* caller's host address(es) */ +#ifdef USE_WTMPDB + int64_t wtmpdb_id; /* ID for wtmpdb_logout */ +#endif }; /* struct logininfo */ /* diff --git a/logintest.c b/logintest.c index 6ee1cdc..1056bba 100644 --- a/logintest.c +++ b/logintest.c @@ -41,9 +41,7 @@ #include #include #include -#ifdef HAVE_TIME_H #include -#endif #include "loginrec.h" diff --git a/m4/openssh.m4 b/m4/openssh.m4 index 176a8d1..f420146 100644 --- a/m4/openssh.m4 +++ b/m4/openssh.m4 @@ -62,7 +62,8 @@ dnl Check that $CC accepts a flag 'check_flag'. If it is supported append dnl 'define_flag' to $CFLAGS. If 'define_flag' is not specified, then append dnl 'check_flag'. AC_DEFUN([OSSH_CHECK_CFLAG_COMPILE], [{ - AC_MSG_CHECKING([if $CC supports compile flag $1]) + ossh_cache_var=AS_TR_SH([ossh_cv_cflag_$1]) + AC_CACHE_CHECK([if $CC supports compile flag $1], [$ossh_cache_var], [ saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR $1" _define_flag="$2" @@ -71,22 +72,23 @@ AC_DEFUN([OSSH_CHECK_CFLAG_COMPILE], [{ [ if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - AC_MSG_RESULT([no]) + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else dnl If we are compiling natively, try running the program. AC_RUN_IFELSE([OSSH_COMPILER_FLAG_TEST_PROGRAM], - [ AC_MSG_RESULT([yes]) + [ eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" ], - [ AC_MSG_RESULT([no, fails at run time]) + [ eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" ], - [ AC_MSG_RESULT([yes]) + [ eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" ], ) fi], - [ AC_MSG_RESULT([no]) + [ eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" ] ) + ]) }]) dnl OSSH_CHECK_CFLAG_LINK(check_flag[, define_flag]) @@ -94,7 +96,8 @@ dnl Check that $CC accepts a flag 'check_flag'. If it is supported append dnl 'define_flag' to $CFLAGS. If 'define_flag' is not specified, then append dnl 'check_flag'. AC_DEFUN([OSSH_CHECK_CFLAG_LINK], [{ - AC_MSG_CHECKING([if $CC supports compile flag $1 and linking succeeds]) + ossh_cache_var=AS_TR_SH([ossh_cv_cflag_$1]) + AC_CACHE_CHECK([if $CC supports compile flag $1 and linking succeeds], [$ossh_cache_var], [ saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR $1" _define_flag="$2" @@ -103,22 +106,23 @@ AC_DEFUN([OSSH_CHECK_CFLAG_LINK], [{ [ if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - AC_MSG_RESULT([no]) + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else dnl If we are compiling natively, try running the program. AC_RUN_IFELSE([OSSH_COMPILER_FLAG_TEST_PROGRAM], - [ AC_MSG_RESULT([yes]) + [ eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" ], - [ AC_MSG_RESULT([no, fails at run time]) + [ eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" ], - [ AC_MSG_RESULT([yes]) + [ eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" ], ) fi], - [ AC_MSG_RESULT([no]) + [ eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" ] ) + ]) }]) dnl OSSH_CHECK_LDFLAG_LINK(check_flag[, define_flag]) @@ -126,7 +130,8 @@ dnl Check that $LD accepts a flag 'check_flag'. If it is supported append dnl 'define_flag' to $LDFLAGS. If 'define_flag' is not specified, then append dnl 'check_flag'. AC_DEFUN([OSSH_CHECK_LDFLAG_LINK], [{ - AC_MSG_CHECKING([if $LD supports link flag $1]) + ossh_cache_var=AS_TR_SH([ossh_cv_ldflag_$1]) + AC_CACHE_CHECK([if $LD supports link flag $1], [$ossh_cache_var], [ saved_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $WERROR $1" _define_flag="$2" @@ -135,22 +140,23 @@ AC_DEFUN([OSSH_CHECK_LDFLAG_LINK], [{ [ if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - AC_MSG_RESULT([no]) + eval "$ossh_cache_var=no" LDFLAGS="$saved_LDFLAGS" else dnl If we are compiling natively, try running the program. AC_RUN_IFELSE([OSSH_COMPILER_FLAG_TEST_PROGRAM], - [ AC_MSG_RESULT([yes]) + [ eval "$ossh_cache_var=yes" LDFLAGS="$saved_LDFLAGS $_define_flag" ], - [ AC_MSG_RESULT([no, fails at run time]) + [ eval "$ossh_cache_var='no, fails at run time'" LDFLAGS="$saved_LDFLAGS" ], - [ AC_MSG_RESULT([yes]) + [ eval "$ossh_cache_var=yes" LDFLAGS="$saved_LDFLAGS $_define_flag" ] ) fi ], - [ AC_MSG_RESULT([no]) + [ eval "$ossh_cache_var=no" LDFLAGS="$saved_LDFLAGS" ] ) + ]) }]) dnl OSSH_CHECK_HEADER_FOR_FIELD(field, header, symbol) diff --git a/mac.c b/mac.c index f3dda66..1760783 100644 --- a/mac.c +++ b/mac.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mac.c,v 1.35 2019/09/06 04:53:27 djm Exp $ */ +/* $OpenBSD: mac.c,v 1.38 2026/03/03 09:57:25 dtucker Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -27,9 +27,9 @@ #include +#include #include #include -#include #include "digest.h" #include "hmac.h" @@ -83,22 +83,13 @@ static const struct macalg macs[] = { char * mac_alg_list(char sep) { - char *ret = NULL, *tmp; - size_t nlen, rlen = 0; + char *ret = NULL; const struct macalg *m; + char sep_str[2] = {sep, '\0'}; + + for (m = macs; m->name != NULL; m++) + xextendf(&ret, sep_str, "%s", m->name); - for (m = macs; m->name != NULL; m++) { - if (ret != NULL) - ret[rlen++] = sep; - nlen = strlen(m->name); - if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) { - free(ret); - return NULL; - } - ret = tmp; - memcpy(ret + rlen, m->name, nlen + 1); - rlen += nlen; - } return ret; } @@ -161,13 +152,13 @@ mac_init(struct sshmac *mac) } int -mac_compute(struct sshmac *mac, u_int32_t seqno, +mac_compute(struct sshmac *mac, uint32_t seqno, const u_char *data, int datalen, u_char *digest, size_t dlen) { static union { u_char m[SSH_DIGEST_MAX_LENGTH]; - u_int64_t for_align; + uint64_t for_align; } u; u_char b[4]; u_char nonce[8]; @@ -207,7 +198,7 @@ mac_compute(struct sshmac *mac, u_int32_t seqno, } int -mac_check(struct sshmac *mac, u_int32_t seqno, +mac_check(struct sshmac *mac, uint32_t seqno, const u_char *data, size_t dlen, const u_char *theirmac, size_t mlen) { diff --git a/mac.h b/mac.h index 0b119d7..04089f4 100644 --- a/mac.h +++ b/mac.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mac.h,v 1.10 2016/07/08 03:44:42 djm Exp $ */ +/* $OpenBSD: mac.h,v 1.11 2026/03/03 09:57:25 dtucker Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -44,9 +44,9 @@ int mac_valid(const char *); char *mac_alg_list(char); int mac_setup(struct sshmac *, char *); int mac_init(struct sshmac *); -int mac_compute(struct sshmac *, u_int32_t, const u_char *, int, +int mac_compute(struct sshmac *, uint32_t, const u_char *, int, u_char *, size_t); -int mac_check(struct sshmac *, u_int32_t, const u_char *, size_t, +int mac_check(struct sshmac *, uint32_t, const u_char *, size_t, const u_char *, size_t); void mac_clear(struct sshmac *); diff --git a/mdoc2man.awk b/mdoc2man.awk index d393ae6..c942ab8 100644 --- a/mdoc2man.awk +++ b/mdoc2man.awk @@ -95,6 +95,8 @@ function add(str) { } else if(match(words[w],"^Ed$")) { skip=1 literal=0 + } else if(match(words[w],"^Dl$")) { + skip=1 } else if(match(words[w],"^Ns$")) { skip=1 if(!nospace) @@ -239,7 +241,7 @@ function add(str) { while(w") - if(option) + for(;option;option--) add("]") if(ext&&!extopt&&!match(line," $")) add(OFS) diff --git a/misc-agent.c b/misc-agent.c new file mode 100644 index 0000000..cb61405 --- /dev/null +++ b/misc-agent.c @@ -0,0 +1,357 @@ +/* $OpenBSD: misc-agent.c,v 1.7 2026/02/11 17:05:32 dtucker Exp $ */ +/* + * Copyright (c) 2025 Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +#include "includes.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "digest.h" +#include "log.h" +#include "misc.h" +#include "pathnames.h" +#include "ssh.h" +#include "xmalloc.h" + +/* stuff shared by agent listeners (ssh-agent and sshd agent forwarding) */ + +#define SOCKET_HOSTNAME_HASHLEN 10 /* length of hostname hash in socket path */ + +/* used for presenting random strings in unix_listener_tmp and hostname_hash */ +static const char presentation_chars[] = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + +/* returns a text-encoded hash of the hostname of specified length (max 64) */ +static char * +hostname_hash(size_t len) +{ + char hostname[NI_MAXHOST], p[65]; + u_char hash[64]; + int r; + size_t l, i; + + l = ssh_digest_bytes(SSH_DIGEST_SHA512); + if (len > 64) { + error_f("bad length %zu >= max %zd", len, l); + return NULL; + } + if (gethostname(hostname, sizeof(hostname)) == -1) { + error_f("gethostname: %s", strerror(errno)); + return NULL; + } + if ((r = ssh_digest_memory(SSH_DIGEST_SHA512, + hostname, strlen(hostname), hash, sizeof(hash))) != 0) { + error_fr(r, "ssh_digest_memory"); + return NULL; + } + memset(p, '\0', sizeof(p)); + for (i = 0; i < l; i++) + p[i] = presentation_chars[ + hash[i] % (sizeof(presentation_chars) - 1)]; + /* debug3_f("hostname \"%s\" => hash \"%s\"", hostname, p); */ + p[len] = '\0'; + return xstrdup(p); +} + +char * +agent_hostname_hash(void) +{ + return hostname_hash(SOCKET_HOSTNAME_HASHLEN); +} + +/* + * Creates a unix listener at a mkstemp(3)-style path, e.g. "/dir/sock.XXXXXX" + * Supplied path is modified to the actual one used. + */ +static int +unix_listener_tmp(char *path, int backlog) +{ + struct sockaddr_un sunaddr; + int good, sock = -1; + size_t i, xstart; + mode_t prev_mask; + + /* Find first 'X' template character back from end of string */ + xstart = strlen(path); + while (xstart > 0 && path[xstart - 1] == 'X') + xstart--; + + memset(&sunaddr, 0, sizeof(sunaddr)); + sunaddr.sun_family = AF_UNIX; + prev_mask = umask(0177); + for (good = 0; !good;) { + sock = -1; + /* Randomise path suffix */ + for (i = xstart; path[i] != '\0'; i++) { + path[i] = presentation_chars[ + arc4random_uniform(sizeof(presentation_chars)-1)]; + } + debug_f("trying path \"%s\"", path); + + if (strlcpy(sunaddr.sun_path, path, + sizeof(sunaddr.sun_path)) >= sizeof(sunaddr.sun_path)) { + error_f("path \"%s\" too long for Unix domain socket", + path); + break; + } + + if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) { + error_f("socket: %.100s", strerror(errno)); + break; + } + if (bind(sock, (struct sockaddr *)&sunaddr, + sizeof(sunaddr)) == -1) { + if (errno == EADDRINUSE) { + error_f("bind \"%s\": %.100s", + path, strerror(errno)); + close(sock); + sock = -1; + continue; + } + error_f("bind \"%s\": %.100s", path, strerror(errno)); + break; + } + if (listen(sock, backlog) == -1) { + error_f("listen \"%s\": %s", path, strerror(errno)); + break; + } + good = 1; + } + umask(prev_mask); + if (good) { + debug3_f("listening on unix socket \"%s\" as fd=%d", + path, sock); + } else if (sock != -1) { + close(sock); + sock = -1; + } + return sock; +} + +/* + * Create a subdirectory under the supplied home directory if it + * doesn't already exist + */ +static int +ensure_mkdir(const char *homedir, const char *subdir) +{ + char *path; + + xasprintf(&path, "%s/%s", homedir, subdir); + if (mkdir(path, 0700) == 0) + debug("created directory %s", path); + else if (errno != EEXIST) { + error_f("mkdir %s: %s", path, strerror(errno)); + free(path); + return -1; + } + free(path); + return 0; +} + +static int +agent_prepare_sockdir(const char *homedir) +{ + if (homedir == NULL || *homedir == '\0' || + ensure_mkdir(homedir, _PATH_SSH_USER_DIR) != 0 || + ensure_mkdir(homedir, _PATH_SSH_AGENT_SOCKET_DIR) != 0) + return -1; + return 0; +} + + +/* Get a path template for an agent socket in the user's homedir */ +static char * +agent_socket_template(const char *homedir, const char *tag) +{ + char *hostnamehash, *ret; + + if ((hostnamehash = hostname_hash(SOCKET_HOSTNAME_HASHLEN)) == NULL) + return NULL; + xasprintf(&ret, "%s/%s/s.%s.%s.XXXXXXXXXX", + homedir, _PATH_SSH_AGENT_SOCKET_DIR, hostnamehash, tag); + free(hostnamehash); + return ret; +} + +int +agent_listener(const char *homedir, const char *tag, int *sockp, char **pathp) +{ + int sock; + char *path; + + *sockp = -1; + *pathp = NULL; + + if (agent_prepare_sockdir(homedir) != 0) + return -1; /* error already logged */ + if ((path = agent_socket_template(homedir, tag)) == NULL) + return -1; /* error already logged */ + if ((sock = unix_listener_tmp(path, SSH_LISTEN_BACKLOG)) == -1) { + free(path); + return -1; /* error already logged */ + } + /* success */ + *sockp = sock; + *pathp = path; + return 0; +} + +static int +socket_is_stale(const char *path) +{ + int fd, r; + struct sockaddr_un sunaddr; + socklen_t l = sizeof(r); + + /* attempt non-blocking connect on socket */ + memset(&sunaddr, '\0', sizeof(sunaddr)); + sunaddr.sun_family = AF_UNIX; + if (strlcpy(sunaddr.sun_path, path, + sizeof(sunaddr.sun_path)) >= sizeof(sunaddr.sun_path)) { + debug_f("path for \"%s\" too long for sockaddr_un", path); + return 0; + } + if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) { + error_f("socket: %s", strerror(errno)); + return 0; + } + set_nonblock(fd); + /* a socket without a listener should yield an error immediately */ + if (connect(fd, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) { + debug_f("connect \"%s\": %s", path, strerror(errno)); + close(fd); + return 1; + } + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &r, &l) == -1) { + debug_f("getsockopt: %s", strerror(errno)); + close(fd); + return 0; + } + if (r != 0) { + debug_f("socket error on %s: %s", path, strerror(errno)); + close(fd); + return 1; + } + close(fd); + debug_f("socket %s seems still active", path); + return 0; +} + +#ifndef HAVE_FSTATAT +# define fstatat(x, y, buf, z) lstat(path, buf) +#endif +#ifndef HAVE_UNLINKAT +# define unlinkat(x, y, z) unlink(path) +#endif + +void +agent_cleanup_stale(const char *homedir, int ignore_hosthash) +{ + DIR *d = NULL; + struct dirent *dp; + struct stat sb; + char *prefix = NULL, *dirpath = NULL, *path = NULL; + struct timespec now, sub, *mtimp = NULL; + + /* Only consider sockets last modified > 1 hour ago */ + if (clock_gettime(CLOCK_REALTIME, &now) != 0) { + error_f("clock_gettime: %s", strerror(errno)); + return; + } + sub.tv_sec = 60 * 60; + sub.tv_nsec = 0; + timespecsub(&now, &sub, &now); + + /* Only consider sockets from the same hostname */ + if (!ignore_hosthash) { + if ((path = agent_hostname_hash()) == NULL) { + error_f("couldn't get hostname hash"); + return; + } + xasprintf(&prefix, "s.%s.", path); + free(path); + path = NULL; + } + + xasprintf(&dirpath, "%s/%s", homedir, _PATH_SSH_AGENT_SOCKET_DIR); + if ((d = opendir(dirpath)) == NULL) { + if (errno != ENOENT) + error_f("opendir \"%s\": %s", dirpath, strerror(errno)); + goto out; + } + + path = NULL; + while ((dp = readdir(d)) != NULL) { + free(path); + xasprintf(&path, "%s/%s", dirpath, dp->d_name); +#ifdef HAVE_DIRENT_D_TYPE + if (dp->d_type != DT_SOCK && dp->d_type != DT_UNKNOWN) + continue; +#endif + if (fstatat(dirfd(d), dp->d_name, + &sb, AT_SYMLINK_NOFOLLOW) != 0 && errno != ENOENT) { + error_f("stat \"%s/%s\": %s", + dirpath, dp->d_name, strerror(errno)); + continue; + } + if (!S_ISSOCK(sb.st_mode)) + continue; +#ifdef HAVE_STRUCT_STAT_ST_MTIM + mtimp = &sb.st_mtim; +#else + sub.tv_sec = sb.st_mtime; + sub.tv_nsec = 0; + mtimp = ⊂ +#endif + if (timespeccmp(mtimp, &now, >)) { + debug3_f("Ignoring recent socket \"%s/%s\"", + dirpath, dp->d_name); + continue; + } + if (!ignore_hosthash && + strncmp(dp->d_name, prefix, strlen(prefix)) != 0) { + debug3_f("Ignoring socket \"%s/%s\" " + "from different host", dirpath, dp->d_name); + continue; + } + if (socket_is_stale(path)) { + debug_f("cleanup stale socket %s", path); + unlinkat(dirfd(d), dp->d_name, 0); + } + } + out: + if (d != NULL) + closedir(d); + free(path); + free(dirpath); + free(prefix); +} + +#undef unlinkat +#undef fstatat diff --git a/misc.c b/misc.c index 1b4b55c..ed3e9d3 100644 --- a/misc.c +++ b/misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.197 2024/09/25 01:24:04 djm Exp $ */ +/* $OpenBSD: misc.c,v 1.213 2026/03/03 09:57:25 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2005-2020 Damien Miller. All rights reserved. @@ -30,28 +30,19 @@ #include #include -#ifdef HAVE_LIBGEN_H -# include -#endif -#ifdef HAVE_POLL_H +#include #include -#endif -#ifdef HAVE_NLIST_H #include -#endif #include #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include #include #include #include -#include #include #include #include @@ -60,11 +51,9 @@ #include #include #include -#ifdef HAVE_PATHS_H -# include +#include #include #include -#endif #ifdef SSH_TUN_OPENBSD #include #endif @@ -101,10 +90,13 @@ rtrim(char *s) if ((i = strlen(s)) == 0) return; - for (i--; i > 0; i--) { + do { + i--; if (isspace((unsigned char)s[i])) s[i] = '\0'; - } + else + break; + } while (i > 0); } /* @@ -128,6 +120,34 @@ strprefix(const char *s, const char *prefix, int ignorecase) return s + prefixlen; } +/* Append string 's' to a NULL-terminated array of strings */ +void +stringlist_append(char ***listp, const char *s) +{ + size_t i = 0; + + if (*listp == NULL) + *listp = xcalloc(2, sizeof(**listp)); + else { + for (i = 0; (*listp)[i] != NULL; i++) + ; /* count */ + *listp = xrecallocarray(*listp, i + 1, i + 2, sizeof(**listp)); + } + (*listp)[i] = xstrdup(s); +} + +void +stringlist_free(char **list) +{ + size_t i = 0; + + if (list == NULL) + return; + for (i = 0; list[i] != NULL; i++) + free(list[i]); + free(list); +} + /* set/unset filedescriptor to non-blocking */ int set_nonblock(int fd) @@ -297,6 +317,10 @@ set_sock_tos(int fd, int tos) #ifndef IP_TOS_IS_BROKEN int af; + if (tos < 0 || tos == INT_MAX) { + debug_f("invalid TOS %d", tos); + return; + } switch ((af = get_sock_af(fd))) { case -1: /* assume not a socket */ @@ -483,7 +507,7 @@ strdelim_internal(char **s, int split_equals) } /* - * Return next token in configuration line; splts on whitespace or a + * Return next token in configuration line; splits on whitespace or a * single '=' character. */ char * @@ -493,7 +517,7 @@ strdelim(char **s) } /* - * Return next token in configuration line; splts on whitespace only. + * Return next token in configuration line; splits on whitespace only. */ char * strdelimw(char **s) @@ -509,7 +533,7 @@ pwcopy(struct passwd *pw) copy->pw_name = xstrdup(pw->pw_name); copy->pw_passwd = xstrdup(pw->pw_passwd == NULL ? "*" : pw->pw_passwd); #ifdef HAVE_STRUCT_PASSWD_PW_GECOS - copy->pw_gecos = xstrdup(pw->pw_gecos); + copy->pw_gecos = xstrdup(pw->pw_gecos == NULL ? "" : pw->pw_gecos); #endif copy->pw_uid = pw->pw_uid; copy->pw_gid = pw->pw_gid; @@ -520,13 +544,32 @@ pwcopy(struct passwd *pw) copy->pw_change = pw->pw_change; #endif #ifdef HAVE_STRUCT_PASSWD_PW_CLASS - copy->pw_class = xstrdup(pw->pw_class); + copy->pw_class = xstrdup(pw->pw_class == NULL ? "" : pw->pw_class); #endif - copy->pw_dir = xstrdup(pw->pw_dir); - copy->pw_shell = xstrdup(pw->pw_shell); + copy->pw_dir = xstrdup(pw->pw_dir == NULL ? "" : pw->pw_dir); + copy->pw_shell = xstrdup(pw->pw_shell == NULL ? "" : pw->pw_shell); return copy; } +void +pwfree(struct passwd *pw) +{ + if (pw == NULL) + return; + free(pw->pw_name); + freezero(pw->pw_passwd, + pw->pw_passwd == NULL ? 0 : strlen(pw->pw_passwd)); +#ifdef HAVE_STRUCT_PASSWD_PW_GECOS + free(pw->pw_gecos); +#endif +#ifdef HAVE_STRUCT_PASSWD_PW_CLASS + free(pw->pw_class); +#endif + free(pw->pw_dir); + free(pw->pw_shell); + freezero(pw, sizeof(*pw)); +} + /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. @@ -578,25 +621,22 @@ a2tun(const char *s, int *remote) return (tun); } -#define SECONDS 1 +#define SECONDS 1.0 #define MINUTES (SECONDS * 60) #define HOURS (MINUTES * 60) #define DAYS (HOURS * 24) #define WEEKS (DAYS * 7) -static char * -scandigits(char *s) -{ - while (isdigit((unsigned char)*s)) - s++; - return s; -} - /* - * Convert a time string into seconds; format is - * a sequence of: + * Convert an interval/duration time string into seconds, which may include + * fractional seconds. + * + * The format is a sequence of: * time[qualifier] * + * This supports fractional values for the seconds value only. All other + * values must be integers. + * * Valid time qualifiers are: * seconds * s|S seconds @@ -606,44 +646,46 @@ scandigits(char *s) * w|W weeks * * Examples: - * 90m 90 minutes - * 1h30m 90 minutes - * 2d 2 days - * 1w 1 week + * 90m 90 minutes + * 1h30m 90 minutes + * 1.5s 1.5 seconds + * 2d 2 days + * 1w 1 week * - * Return -1 if time string is invalid. + * Returns <0.0 if the time string is invalid. */ -int -convtime(const char *s) +double +convtime_double(const char *s) { - int secs, total = 0, multiplier; - char *p, *os, *np, c = 0; - const char *errstr; + double val, total_sec = 0.0, multiplier; + const char *p, *start_p; + char *endp; + int seen_seconds = 0; if (s == NULL || *s == '\0') - return -1; - p = os = strdup(s); /* deal with const */ - if (os == NULL) - return -1; - - while (*p) { - np = scandigits(p); - if (np) { - c = *np; - *np = '\0'; - } - secs = (int)strtonum(p, 0, INT_MAX, &errstr); - if (errstr) - goto fail; - *np = c; - - multiplier = 1; - switch (c) { + return -1.0; + + for (p = s; *p != '\0';) { + if (!isdigit((unsigned char)*p) && *p != '.') + return -1.0; + + errno = 0; + if ((val = strtod(p, &endp)) < 0 || errno != 0 || p == endp) + return -1.0; + /* Allow only decimal forms */ + if (p + strspn(p, "0123456789.") != endp) + return -1.0; + start_p = p; + p = endp; + + switch (*p) { case '\0': - np--; /* back up */ - break; + /* FALLTHROUGH */ case 's': case 'S': + if (seen_seconds++) + return -1.0; + multiplier = SECONDS; break; case 'm': case 'M': @@ -662,23 +704,44 @@ convtime(const char *s) multiplier = WEEKS; break; default: - goto fail; + return -1.0; } - if (secs > INT_MAX / multiplier) - goto fail; - secs *= multiplier; - if (total > INT_MAX - secs) - goto fail; - total += secs; - if (total < 0) - goto fail; - p = ++np; - } - free(os); - return total; -fail: - free(os); - return -1; + + /* Special handling if this was a decimal */ + if (memchr(start_p, '.', endp - start_p) != NULL) { + /* Decimal point present */ + if (multiplier > 1.0) + return -1.0; /* No fractionals for non-seconds */ + /* For seconds, ensure digits follow */ + if (!isdigit((unsigned char)*(endp - 1))) + return -1.0; + } + + total_sec += val * multiplier; + + if (*p != '\0') + p++; + } + return total_sec; +} + +/* + * Same as convtime_double() above but fractional seconds are ignored. + * Return -1 if time string is invalid. + */ +int +convtime(const char *s) +{ + double sec_val; + + if ((sec_val = convtime_double(s)) < 0.0) + return -1; + + /* Check for overflow into int */ + if (sec_val < 0 || sec_val > INT_MAX) + return -1; + + return (int)sec_val; } #define TF_BUFS 8 @@ -990,7 +1053,7 @@ urldecode(const char *src) size_t srclen; if ((srclen = strlen(src)) >= SIZE_MAX) - fatal_f("input too large"); + return NULL; ret = xmalloc(srclen + 1); for (dst = ret; *src != '\0'; src++) { switch (*src) { @@ -998,9 +1061,10 @@ urldecode(const char *src) *dst++ = ' '; break; case '%': + /* note: don't allow \0 characters */ if (!isxdigit((unsigned char)src[1]) || !isxdigit((unsigned char)src[2]) || - (ch = hexchar(src + 1)) == -1) { + (ch = hexchar(src + 1)) == -1 || ch == 0) { free(ret); return NULL; } @@ -1596,66 +1660,66 @@ xextendf(char **sp, const char *sep, const char *fmt, ...) } -u_int64_t +uint64_t get_u64(const void *vp) { const u_char *p = (const u_char *)vp; - u_int64_t v; + uint64_t v; - v = (u_int64_t)p[0] << 56; - v |= (u_int64_t)p[1] << 48; - v |= (u_int64_t)p[2] << 40; - v |= (u_int64_t)p[3] << 32; - v |= (u_int64_t)p[4] << 24; - v |= (u_int64_t)p[5] << 16; - v |= (u_int64_t)p[6] << 8; - v |= (u_int64_t)p[7]; + v = (uint64_t)p[0] << 56; + v |= (uint64_t)p[1] << 48; + v |= (uint64_t)p[2] << 40; + v |= (uint64_t)p[3] << 32; + v |= (uint64_t)p[4] << 24; + v |= (uint64_t)p[5] << 16; + v |= (uint64_t)p[6] << 8; + v |= (uint64_t)p[7]; return (v); } -u_int32_t +uint32_t get_u32(const void *vp) { const u_char *p = (const u_char *)vp; - u_int32_t v; + uint32_t v; - v = (u_int32_t)p[0] << 24; - v |= (u_int32_t)p[1] << 16; - v |= (u_int32_t)p[2] << 8; - v |= (u_int32_t)p[3]; + v = (uint32_t)p[0] << 24; + v |= (uint32_t)p[1] << 16; + v |= (uint32_t)p[2] << 8; + v |= (uint32_t)p[3]; return (v); } -u_int32_t +uint32_t get_u32_le(const void *vp) { const u_char *p = (const u_char *)vp; - u_int32_t v; + uint32_t v; - v = (u_int32_t)p[0]; - v |= (u_int32_t)p[1] << 8; - v |= (u_int32_t)p[2] << 16; - v |= (u_int32_t)p[3] << 24; + v = (uint32_t)p[0]; + v |= (uint32_t)p[1] << 8; + v |= (uint32_t)p[2] << 16; + v |= (uint32_t)p[3] << 24; return (v); } -u_int16_t +uint16_t get_u16(const void *vp) { const u_char *p = (const u_char *)vp; - u_int16_t v; + uint16_t v; - v = (u_int16_t)p[0] << 8; - v |= (u_int16_t)p[1]; + v = (uint16_t)p[0] << 8; + v |= (uint16_t)p[1]; return (v); } void -put_u64(void *vp, u_int64_t v) +put_u64(void *vp, uint64_t v) { u_char *p = (u_char *)vp; @@ -1670,7 +1734,7 @@ put_u64(void *vp, u_int64_t v) } void -put_u32(void *vp, u_int32_t v) +put_u32(void *vp, uint32_t v) { u_char *p = (u_char *)vp; @@ -1681,7 +1745,7 @@ put_u32(void *vp, u_int32_t v) } void -put_u32_le(void *vp, u_int32_t v) +put_u32_le(void *vp, uint32_t v) { u_char *p = (u_char *)vp; @@ -1692,7 +1756,7 @@ put_u32_le(void *vp, u_int32_t v) } void -put_u16(void *vp, u_int16_t v) +put_u16(void *vp, uint16_t v) { u_char *p = (u_char *)vp; @@ -1766,7 +1830,7 @@ monotime(void) struct timespec ts; monotime_ts(&ts); - return ts.tv_sec; + return (ts.tv_sec); } double @@ -1775,11 +1839,11 @@ monotime_double(void) struct timespec ts; monotime_ts(&ts); - return ts.tv_sec + ((double)ts.tv_nsec / 1000000000); + return (double)ts.tv_sec + (double)ts.tv_nsec / 1000000000.0; } void -bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen) +bandwidth_limit_init(struct bwlimit *bw, uint64_t kbps, size_t buflen) { bw->buflen = buflen; bw->rate = kbps; @@ -1793,7 +1857,7 @@ bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen) void bandwidth_limit(struct bwlimit *bw, size_t read_len) { - u_int64_t waitlen; + uint64_t waitlen; struct timespec ts, rm; bw->lamt += read_len; @@ -1885,9 +1949,10 @@ static const struct { { "cs7", IPTOS_DSCP_CS7 }, { "ef", IPTOS_DSCP_EF }, { "le", IPTOS_DSCP_LE }, - { "lowdelay", IPTOS_LOWDELAY }, - { "throughput", IPTOS_THROUGHPUT }, - { "reliability", IPTOS_RELIABILITY }, + { "va", IPTOS_DSCP_VA }, + { "lowdelay", INT_MIN }, /* deprecated */ + { "throughput", INT_MIN }, /* deprecated */ + { "reliability", INT_MIN }, /* deprecated */ { NULL, -1 } }; @@ -1982,7 +2047,7 @@ sock_set_v6only(int s) #if defined(IPV6_V6ONLY) && !defined(__OpenBSD__) int on = 1; - debug3("%s: set socket %d IPV6_V6ONLY", __func__, s); + debug3_f("set socket %d IPV6_V6ONLY", s); if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) == -1) error("setsockopt IPV6_V6ONLY: %s", strerror(errno)); #endif @@ -2254,7 +2319,7 @@ int safe_path(const char *name, struct stat *stp, const char *pw_dir, uid_t uid, char *err, size_t errlen) { - char buf[PATH_MAX], homedir[PATH_MAX]; + char buf[PATH_MAX], buf2[PATH_MAX], homedir[PATH_MAX]; char *cp; int comparehome = 0; struct stat st; @@ -2280,7 +2345,12 @@ safe_path(const char *name, struct stat *stp, const char *pw_dir, /* for each component of the canonical path, walking upwards */ for (;;) { - if ((cp = dirname(buf)) == NULL) { + /* + * POSIX allows dirname to modify its argument and return a + * pointer into it, so make a copy to avoid overlapping strlcpy. + */ + strlcpy(buf2, buf, sizeof(buf2)); + if ((cp = dirname(buf2)) == NULL) { snprintf(err, errlen, "dirname() failed"); return -1; } @@ -2406,7 +2476,8 @@ valid_domain(char *name, int makelower, const char **errstr) strlcpy(errbuf, "empty domain name", sizeof(errbuf)); goto bad; } - if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0])) { + if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0]) && + name[0] != '_' /* technically invalid, but common */) { snprintf(errbuf, sizeof(errbuf), "domain name \"%.100s\" " "starts with invalid character", name); goto bad; @@ -2534,8 +2605,10 @@ format_absolute_time(uint64_t t, char *buf, size_t len) time_t tt = t > SSH_TIME_T_MAX ? SSH_TIME_T_MAX : t; struct tm tm; - localtime_r(&tt, &tm); - strftime(buf, len, "%Y-%m-%dT%H:%M:%S", &tm); + if (localtime_r(&tt, &tm) == NULL) + strlcpy(buf, "UNKNOWN-TIME", len); + else + strftime(buf, len, "%Y-%m-%dT%H:%M:%S", &tm); } /* @@ -3057,7 +3130,7 @@ ptimeout_isset(struct timespec *pt) int lib_contains_symbol(const char *path, const char *s) { -#ifdef HAVE_NLIST_H +#ifdef HAVE_NLIST struct nlist nl[2]; int ret = -1, r; @@ -3077,7 +3150,7 @@ lib_contains_symbol(const char *path, const char *s) out: free(nl[0].n_name); return ret; -#else /* HAVE_NLIST_H */ +#else /* HAVE_NLIST */ int fd, ret = -1; struct stat st; void *m = NULL; @@ -3119,7 +3192,7 @@ lib_contains_symbol(const char *path, const char *s) munmap(m, sz); close(fd); return ret; -#endif /* HAVE_NLIST_H */ +#endif /* HAVE_NLIST */ } int @@ -3137,3 +3210,18 @@ signal_is_crash(int sig) } return 0; } + +char * +get_homedir(void) +{ + char *cp; + struct passwd *pw; + + if ((cp = getenv("HOME")) != NULL && *cp != '\0') + return xstrdup(cp); + + if ((pw = getpwuid(getuid())) != NULL && *pw->pw_dir != '\0') + return xstrdup(pw->pw_dir); + + return NULL; +} diff --git a/misc.h b/misc.h index efecdf1..791876c 100644 --- a/misc.h +++ b/misc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.h,v 1.110 2024/09/25 01:24:04 djm Exp $ */ +/* $OpenBSD: misc.h,v 1.116 2026/03/11 09:10:59 dtucker Exp $ */ /* * Author: Tatu Ylonen @@ -59,6 +59,8 @@ void skip_space(char **); const char *strprefix(const char *, const char *, int); char *strdelim(char **); char *strdelimw(char **); +void stringlist_append(char ***listp, const char *s); +void stringlist_free(char **list); int set_nonblock(int); int unset_nonblock(int); void set_nodelay(int); @@ -79,7 +81,9 @@ char *colon(char *); int parse_user_host_path(const char *, char **, char **, char **); int parse_user_host_port(const char *, char **, char **, int *); int parse_uri(const char *, const char *, char **, char **, int *, char **); +double convtime_double(const char *); int convtime(const char *); +double convtime_double(const char *); const char *fmt_timeframe(time_t t); int tilde_expand(const char *, uid_t, char **); char *tilde_expand_filename(const char *, uid_t); @@ -108,10 +112,13 @@ int parse_pattern_interval(const char *, char **, int *); int path_absolute(const char *); int stdfd_devnull(int, int, int); int lib_contains_symbol(const char *, const char *); +char *get_homedir(void); void sock_set_v6only(int); struct passwd *pwcopy(struct passwd *); +void pwfree(struct passwd *); /* NB. only use with pwcopy */ + const char *ssh_gai_strerror(int); typedef void privdrop_fn(struct passwd *); @@ -153,34 +160,34 @@ int tun_open(int, int, char **); #define PORT_STREAMLOCAL -2 /* Functions to extract or store big-endian words of various sizes */ -u_int64_t get_u64(const void *) +uint64_t get_u64(const void *) __attribute__((__bounded__( __minbytes__, 1, 8))); -u_int32_t get_u32(const void *) +uint32_t get_u32(const void *) __attribute__((__bounded__( __minbytes__, 1, 4))); -u_int16_t get_u16(const void *) +uint16_t get_u16(const void *) __attribute__((__bounded__( __minbytes__, 1, 2))); -void put_u64(void *, u_int64_t) +void put_u64(void *, uint64_t) __attribute__((__bounded__( __minbytes__, 1, 8))); -void put_u32(void *, u_int32_t) +void put_u32(void *, uint32_t) __attribute__((__bounded__( __minbytes__, 1, 4))); -void put_u16(void *, u_int16_t) +void put_u16(void *, uint16_t) __attribute__((__bounded__( __minbytes__, 1, 2))); /* Little-endian store/load, used by umac.c */ -u_int32_t get_u32_le(const void *) +uint32_t get_u32_le(const void *) __attribute__((__bounded__(__minbytes__, 1, 4))); -void put_u32_le(void *, u_int32_t) +void put_u32_le(void *, uint32_t) __attribute__((__bounded__(__minbytes__, 1, 4))); struct bwlimit { size_t buflen; - u_int64_t rate; /* desired rate in kbit/s */ - u_int64_t thresh; /* threshold after which we'll check timers */ - u_int64_t lamt; /* amount written in last timer interval */ + uint64_t rate; /* desired rate in kbit/s */ + uint64_t thresh; /* threshold after which we'll check timers */ + uint64_t lamt; /* amount written in last timer interval */ struct timeval bwstart, bwend; }; -void bandwidth_limit_init(struct bwlimit *, u_int64_t, size_t); +void bandwidth_limit_init(struct bwlimit *, uint64_t, size_t); void bandwidth_limit(struct bwlimit *, size_t); int parse_ipqos(const char *); @@ -231,6 +238,11 @@ int ptimeout_get_ms(struct timespec *pt); struct timespec *ptimeout_get_tsp(struct timespec *pt); int ptimeout_isset(struct timespec *pt); +/* misc-agent.c */ +char *agent_hostname_hash(void); +int agent_listener(const char *, const char *, int *, char **); +void agent_cleanup_stale(const char *, int); + /* readpass.c */ #define RP_ECHO 0x0001 @@ -258,4 +270,10 @@ int signal_is_crash(int); /* On OpenBSD time_t is int64_t which is long long. */ /* #define SSH_TIME_T_MAX LLONG_MAX */ +#define FD_CLOSEONEXEC(x) do { \ + if (fcntl(x, F_SETFD, FD_CLOEXEC) == -1) \ + fatal_f("fcntl(%d, F_SETFD, FD_CLOEXEC): %s", x, \ + strerror(errno)); \ +} while (0) + #endif /* _MISC_H */ diff --git a/mlkem768.sh b/mlkem768.sh index 3d12b2e..bec372a 100644 --- a/mlkem768.sh +++ b/mlkem768.sh @@ -1,17 +1,18 @@ #!/bin/sh -# $OpenBSD: mlkem768.sh,v 1.3 2024/10/27 02:06:01 djm Exp $ +# $OpenBSD: mlkem768.sh,v 1.5 2025/11/13 05:13:06 djm Exp $ # Placed in the Public Domain. # #WANT_LIBCRUX_REVISION="origin/main" -WANT_LIBCRUX_REVISION="84c5d87b3092c59294345aa269ceefe0eb97cc35" +WANT_LIBCRUX_REVISION="core-models-v0.0.4" +BASE="libcrux/libcrux-ml-kem/extracts/c_header_only/generated" FILES=" - libcrux/libcrux-ml-kem/cg/eurydice_glue.h - libcrux/libcrux-ml-kem/cg/libcrux_core.h - libcrux/libcrux-ml-kem/cg/libcrux_ct_ops.h - libcrux/libcrux-ml-kem/cg/libcrux_sha3_portable.h - libcrux/libcrux-ml-kem/cg/libcrux_mlkem768_portable.h + $BASE/eurydice_glue.h + $BASE/libcrux_mlkem_core.h + $BASE/libcrux_ct_ops.h + $BASE/libcrux_sha3_portable.h + $BASE/libcrux_mlkem768_portable.h " START="$PWD" @@ -40,14 +41,80 @@ echo '/*' cat libcrux/LICENSE-MIT | sed 's/^/ * /;s/ *$//' echo ' */' echo -echo '#if !defined(__GNUC__) || (__GNUC__ < 2)' -echo '# define __attribute__(x)' -echo '#endif' -echo '#define KRML_MUSTINLINE inline' -echo '#define KRML_NOINLINE __attribute__((noinline, unused))' -echo '#define KRML_HOST_EPRINTF(...)' -echo '#define KRML_HOST_EXIT(x) fatal_f("internal error")' -echo + +LSHIFT="<<" +cat << _EOF +#if !defined(__GNUC__) || (__GNUC__ < 2) +# define __attribute__(x) +#endif +#define KRML_MUSTINLINE inline +#define KRML_NOINLINE __attribute__((noinline, unused)) +#define KRML_HOST_EPRINTF(...) +#define KRML_HOST_EXIT(x) fatal_f("internal error") + +static inline void +store64_le(uint8_t dst[8], uint64_t src) +{ + dst[0] = src & 0xff; + dst[1] = (src >> 8) & 0xff; + dst[2] = (src >> 16) & 0xff; + dst[3] = (src >> 24) & 0xff; + dst[4] = (src >> 32) & 0xff; + dst[5] = (src >> 40) & 0xff; + dst[6] = (src >> 48) & 0xff; + dst[7] = (src >> 56) & 0xff; +} + +static inline void +store32_le(uint8_t dst[4], uint32_t src) +{ + dst[0] = src & 0xff; + dst[1] = (src >> 8) & 0xff; + dst[2] = (src >> 16) & 0xff; + dst[3] = (src >> 24) & 0xff; +} + +static inline void +store32_be(uint8_t dst[4], uint32_t src) +{ + dst[0] = (src >> 24) & 0xff; + dst[1] = (src >> 16) & 0xff; + dst[2] = (src >> 8) & 0xff; + dst[3] = src & 0xff; +} + +static inline uint64_t +load64_le(uint8_t src[8]) +{ + return (uint64_t)(src[0]) | + ((uint64_t)(src[1]) $LSHIFT 8) | + ((uint64_t)(src[2]) $LSHIFT 16) | + ((uint64_t)(src[3]) $LSHIFT 24) | + ((uint64_t)(src[4]) $LSHIFT 32) | + ((uint64_t)(src[5]) $LSHIFT 40) | + ((uint64_t)(src[6]) $LSHIFT 48) | + ((uint64_t)(src[7]) $LSHIFT 56); +} + +static inline uint32_t +load32_le(uint8_t src[4]) +{ + return (uint32_t)(src[0]) | + ((uint32_t)(src[1]) $LSHIFT 8) | + ((uint32_t)(src[2]) $LSHIFT 16) | + ((uint32_t)(src[3]) $LSHIFT 24); +} + +#ifdef MISSING_BUILTIN_POPCOUNT +static inline unsigned int +__builtin_popcount(unsigned int num) +{ + const int v[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; + return v[num & 0xf] + v[(num >> 4) & 0xf]; +} +#endif + +_EOF for i in $FILES; do echo "/* from $i */" @@ -58,11 +125,9 @@ for i in $FILES; do -e 's/[ ]*$//' \ $i | \ case "$i" in - */libcrux-ml-kem/cg/eurydice_glue.h) - # Replace endian functions with versions that work. - perl -0777 -pe 's/(static inline void core_num__u64_9__to_le_bytes.*\n)([^}]*\n)/\1 v = htole64(v);\n\2/' | - perl -0777 -pe 's/(static inline uint64_t core_num__u64_9__from_le_bytes.*?)return v;/\1return le64toh(v);/s' | - perl -0777 -pe 's/(static inline uint32_t core_num__u32_8__from_le_bytes.*?)return v;/\1return le32toh(v);/s' + */eurydice_glue.h) + # Replace endian function for consistency. + perl -0777 -pe 's/(static inline void core_num__u32__to_be_bytes.*\n)([^}]*\n)/\1 store32_be(dst, src);\n/' ;; # Default: pass through. *) @@ -75,11 +140,10 @@ done echo echo '/* rename some types to be a bit more ergonomic */' echo '#define libcrux_mlkem768_keypair libcrux_ml_kem_mlkem768_MlKem768KeyPair_s' -echo '#define libcrux_mlkem768_pk_valid_result Option_92_s' -echo '#define libcrux_mlkem768_pk libcrux_ml_kem_types_MlKemPublicKey_15_s' -echo '#define libcrux_mlkem768_sk libcrux_ml_kem_types_MlKemPrivateKey_55_s' +echo '#define libcrux_mlkem768_pk libcrux_ml_kem_types_MlKemPublicKey_30_s' +echo '#define libcrux_mlkem768_sk libcrux_ml_kem_types_MlKemPrivateKey_d9_s' echo '#define libcrux_mlkem768_ciphertext libcrux_ml_kem_mlkem768_MlKem768Ciphertext_s' -echo '#define libcrux_mlkem768_enc_result tuple_3c_s' +echo '#define libcrux_mlkem768_enc_result tuple_c2_s' ) > libcrux_mlkem768_sha3.h_new # Do some checks on the resultant file @@ -132,13 +196,13 @@ int main(void) { return 0; } _EOF -cc -Wall -Wextra -Wno-unused-parameter -o libcrux_mlkem768_sha3_check \ +cc -Wall -Wextra -Wno-unused-parameter -I . -o libcrux_mlkem768_sha3_check \ libcrux_mlkem768_sha3_check.c ./libcrux_mlkem768_sha3_check # Extract PRNG inputs; there's no nice #defines for these -key_pair_rng_len=`sed -e '/^libcrux_ml_kem_mlkem768_portable_kyber_generate_key_pair[(]$/,/[)] {$/!d' < libcrux_mlkem768_sha3.h_new | grep 'uint8_t randomness\[[0-9]*U\][)]' | sed 's/.*randomness\[\([0-9]*\)U\].*/\1/'` -enc_rng_len=`sed -e '/^static inline tuple_3c libcrux_ml_kem_mlkem768_portable_kyber_encapsulate[(]$/,/[)] {$/!d' < libcrux_mlkem768_sha3.h_new | grep 'uint8_t randomness\[[0-9]*U\][)]' | sed 's/.*randomness\[\([0-9]*\)U\].*/\1/'` +key_pair_rng_len=`grep '^libcrux_ml_kem_mlkem768_portable_generate_key_pair.*randomness' libcrux_mlkem768_sha3.h_new | sed 's/.*randomness[[]//;s/\].*//'` +enc_rng_len=`sed -e '/^static inline tuple_c2 libcrux_ml_kem_mlkem768_portable_encapsulate[(]$/,/[)] {$/!d' < libcrux_mlkem768_sha3.h_new | grep 'uint8_t randomness\[[0-9]*U\][)]' | sed 's/.*randomness\[\([0-9]*\)U\].*/\1/'` test -z "$key_pair_rng_len" && die "couldn't find size of libcrux_ml_kem_mlkem768_portable_kyber_generate_key_pair randomness argument" test -z "$enc_rng_len" && die "couldn't find size of libcrux_ml_kem_mlkem768_portable_kyber_encapsulate randomness argument" diff --git a/moduli b/moduli index bebd3a9..f5e0bba 100644 --- a/moduli +++ b/moduli @@ -1,412 +1,586 @@ -# $OpenBSD: moduli,v 1.38 2024/08/21 07:06:27 dtucker Exp $ +# $OpenBSD: moduli,v 1.41 2025/10/11 23:39:14 dtucker Exp $ # Time Type Tests Tries Size Generator Modulus -20240326013051 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85DDC5DFB -20240326013055 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85DF8EE9F -20240326013100 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85E15B2AF -20240326013115 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85E8800BB -20240326013121 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85EA93D9F -20240326013127 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85ED33B77 -20240326013129 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85EDE96FB -20240326013133 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85EFDC7AB -20240326013135 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85F004B07 -20240326013147 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85F5A20FB -20240326013151 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85F780007 -20240326013154 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85F873847 -20240326013155 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85F8792BF -20240326013158 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85F99602B -20240326013212 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85FFDCCE7 -20240326013219 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A86033F8F7 -20240326013239 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A860C92607 -20240326013244 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A860EACC9F -20240326013252 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A8612623A3 -20240326013254 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A86131122B -20240326013256 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A86137AE5B -20240326013316 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A861CE9FAB -20240326013319 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A861DDF033 -20240326013322 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A861F71477 -20240326013330 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A8622DF73F -20240326013333 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A8623FA97B -20240326013347 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A862A6F8D3 -20240326013357 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A862EDADB3 -20240326013401 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A86306A44F -20240326013402 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A8630A4F4F -20240326013406 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A86329C6AF -20240326013412 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A8634D56D7 -20240326013433 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A863ECB6D7 -20240326013438 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A8640E99FF -20240326013448 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A86456D45B -20240326013455 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A8648DB9CF -20240326013456 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A86490C78B -20240326013506 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A864D48787 -20240326013511 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A864F4C14B -20240326013522 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A86546E877 -20240326013524 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A8654FB6D3 -20240326013529 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A865742D0B -20240326013534 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A8659900A3 -20240326013537 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A865A3FE37 -20240326013538 2 6 100 2047 5 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F049F51F -20240326013547 2 6 100 2047 2 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F0859D0B -20240326013554 2 6 100 2047 5 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F0BBD077 -20240326013607 2 6 100 2047 2 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F11279FB -20240326013628 2 6 100 2047 2 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F1B2B0DB -20240326013645 2 6 100 2047 5 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F22EA4A7 -20240326013653 2 6 100 2047 2 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F266CCCB -20240326013656 2 6 100 2047 2 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F27B8CC3 -20240326013704 2 6 100 2047 2 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F2B6898B -20240326013728 2 6 100 2047 5 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F3661F27 -20240326013732 2 6 100 2047 5 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F382F33F -20240326013755 2 6 100 2047 2 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F42B19A3 -20240326013815 2 6 100 2047 5 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F4BFFC7F -20240326013816 2 6 100 2047 2 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F4C4D313 -20240326013818 2 6 100 2047 5 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F4CB895F -20240326013838 2 6 100 2047 2 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F55F34E3 -20240326013843 2 6 100 2047 2 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F581582B -20240326013845 2 6 100 2047 5 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F58BB9BF -20240326013904 2 6 100 2047 2 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F61FCE5B -20240326013920 2 6 100 2047 5 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F69490CF -20240326013923 2 6 100 2047 2 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F6A8041B -20240326013953 2 6 100 2047 2 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F7815AF3 -20240326014006 2 6 100 2047 5 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F7E1576F -20240326014014 2 6 100 2047 5 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F818E747 -20240326014019 2 6 100 2047 5 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F83E49A7 -20240326014532 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A3425DB7F -20240326014544 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A34464EAF -20240326014614 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A349D1663 -20240326014629 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A34C39EC3 -20240326014710 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A3544B6B7 -20240326014727 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A3574A89B -20240326014741 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A359DA947 -20240326014823 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A361FBA5F -20240326014832 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A36377BB3 -20240326015023 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A37A19A47 -20240326015025 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A37A30F2B -20240326015030 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A37AD1B0F -20240326015038 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A37C0B3FF -20240326015116 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A38348BB3 -20240326015159 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A38BA81C7 -20240326015331 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A39D93F9B -20240326015416 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A3A61FCDF -20240326015505 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A3AFA877F -20240326015516 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A3B1796B3 -20240326015601 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A3BA5A777 -20240326015813 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A3D516827 -20240326020106 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A3F7A7897 -20240326020108 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A3F7B337B -20240326020156 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A4012DDF3 -20240326020241 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A409D1FB7 -20240326020357 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A418A36C7 -20240326020359 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A418AC37F -20240326020434 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A41F5DCD3 -20240326020621 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A434E3E3F -20240326020642 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A438BE4BB -20240326020655 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A43ADA137 -20240326020708 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A43D0D1CB -20240326020800 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A44709DB3 -20240326020836 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A44DBD6DB -20240326020854 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A450CF663 -20240326020934 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A458A51DB -20240326021106 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A3512585539C8487 -20240326021134 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A351258553F5040F -20240326021206 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855453B76F -20240326021324 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855546DBDB -20240326021407 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A351258555BDDCF3 -20240326021424 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A351258555F11B9F -20240326021450 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855644DDE3 -20240326021458 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855656D6E7 -20240326021614 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A351258557488DE3 -20240326021659 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A351258557D16D53 -20240326021718 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A3512585580918BB -20240326021822 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A351258558D0013B -20240326021836 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A351258558F7A96B -20240326021921 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855982467F -20240326021932 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A351258559A0BC87 -20240326022009 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855A12A95B -20240326022029 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855A4C1027 -20240326022038 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855A608723 -20240326022102 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855AA76F27 -20240326022132 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855B050E7B -20240326022301 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855C2121F3 -20240326022441 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855D60DD03 -20240326022451 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855D7D2637 -20240326022516 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855DC6F6EF -20240326022530 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855DEDE3DB -20240326022711 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855F35973F -20240326022824 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125856017684F -20240326022834 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125856032C153 -20240326022854 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A3512585606C9E9F -20240326022919 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A351258560B97F3B -20240326023041 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A351258561B88E3B -20240326023119 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A3512585622F17B3 -20240326023135 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A3512585625E20DB -20240326023142 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A3512585626E1567 -20240326023229 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A3512585630054CB -20240326023255 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A3512585634C7DFB -20240326023307 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A3512585636F2A3B -20240326023310 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125856371CA8F -20240326023417 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A351258564487EA3 -20240326023451 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A351258564AFE53B -20240326024347 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF8181186E03B3 -20240326024508 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF818118EEB0A3 -20240326024849 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81811A4ECE4B -20240326025526 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81811CD141E3 -20240326025628 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81811D32676B -20240326030110 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81811EF7F1E3 -20240326030518 2 6 100 4095 5 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF818120788D47 -20240326031719 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF818125002673 -20240326031926 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF818125C6B433 -20240326031951 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF818125E6335B -20240326032742 2 6 100 4095 5 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF818128EAC3E7 -20240326032936 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF818129980033 -20240326032952 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF818129AAC3DB -20240326033059 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81812A0B8603 -20240326033458 2 6 100 4095 5 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81812B8E0D07 -20240326033533 2 6 100 4095 5 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81812BBB8B97 -20240326033606 2 6 100 4095 5 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81812BE87FF7 -20240326033629 2 6 100 4095 5 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81812C03788F -20240326033712 2 6 100 4095 5 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81812C3FAF07 -20240326034008 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81812D534F8B -20240326034204 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81812E080CA3 -20240326034508 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81812F2F5493 -20240326034751 2 6 100 4095 5 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF8181302AABC7 -20240326034806 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF8181303CD8D3 -20240326034823 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF8181304F3DCB -20240326035043 2 6 100 4095 5 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF8181312A3FE7 -20240326035348 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF8181324BFA5B -20240326035602 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF8181331F2E53 -20240326035702 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF818133769453 -20240326035737 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF818133AA336B -20240326035756 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF818133C16B8B -20240326040216 2 6 100 4095 5 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81813553AD37 -20240326040447 2 6 100 4095 5 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81813644788F -20240326040552 2 6 100 4095 5 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF818136A4C7F7 -20240326040951 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D80EA89E4B -20240326042517 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D8147E15B3 -20240326042616 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D814D61A3B -20240326043713 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D818FD20D3 -20240326043724 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D819078123 -20240326043742 2 6 100 4095 5 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D8191EAEFF -20240326044025 2 6 100 4095 5 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D81A204197 -20240326044258 2 6 100 4095 5 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D81B145927 -20240326044447 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D81BB935AB -20240326044534 2 6 100 4095 5 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D81BFCFA6F -20240326045348 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D81F0CEB6B -20240326045438 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D81F582F4B -20240326045630 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D82007A843 -20240326045745 2 6 100 4095 5 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D820792B27 -20240326045949 2 6 100 4095 5 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D82142CB8F -20240326045957 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D82148EA73 -20240326050355 2 6 100 4095 5 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D822CAC6BF -20240326050713 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D8240BBCC3 -20240326050731 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D824214D3B -20240326050903 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D824ACACFB -20240326051214 2 6 100 4095 5 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D825DF67F7 -20240326051332 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D826515C63 -20240326051747 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D827E42F0B -20240326051831 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D828243B8B -20240326051843 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D82831A223 -20240326052417 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D82A48CE23 -20240326052731 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D82B78A8F3 -20240326052959 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D82C5D399B -20240326053126 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D82CE5BB4B -20240326060038 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A3C767FD7 -20240326060444 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A3CF77C3B -20240326070240 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A4448EF33 -20240326073131 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A47DAE05B -20240326073415 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A482BBA27 -20240326080953 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A4CB6AE7F -20240326081127 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A4CDF5A0B -20240326093032 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A56B6523B -20240326093454 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A573897EB -20240326093728 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A57820693 -20240326094259 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A5829EAF7 -20240326094948 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A58FD0FEF -20240326101231 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A5BDEBEE3 -20240326101412 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A5C09FFB3 -20240326102704 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A5DAD12BF -20240326103806 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A5F05465F -20240326105506 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A611EE2E3 -20240326112146 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A647870E3 -20240326114154 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A6707EC03 -20240326114315 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A6729353B -20240326122735 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A6CC0FBB3 -20240326123728 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A6DF24D2F -20240326130541 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A71768773 -20240326130743 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A71AF6A1B -20240326132826 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A743654E3 -20240326134513 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A76478D13 -20240326134939 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A76C9E817 -20240326135416 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A7755E8B7 -20240326143409 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A7C397F2F -20240326144117 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A7D13AF93 -20240326150017 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A7F704F7F -20240326150157 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A7F9F468F -20240326150526 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A8005826B -20240326150739 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A8045FDAF -20240326151012 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A808FF207 -20240326151536 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A81343BEB -20240326162321 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5AD9F98F93F -20240326163529 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADA11D7CC3 -20240326163654 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADA142310B -20240326165530 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADA394A593 -20240326171340 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADA5C7FE3B -20240326175630 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADAB35A653 -20240326175808 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADAB62C48F -20240326184011 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADB0B50FD7 -20240326184335 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADB1203D2F -20240326185246 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADB2435AB7 -20240326190020 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADB333EDAB -20240326190122 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADB34BD947 -20240326191114 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADB482E3D7 -20240326192702 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADB67FBDFB -20240326195941 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADBAA83D13 -20240326200115 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADBAD40AEF -20240326201633 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADBCB670E7 -20240326203821 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADBF6DC6B3 -20240326204751 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADC094E45B -20240326205334 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADC1441637 -20240326211827 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADC45F0E3F -20240326212459 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADC52DBD1B -20240326214659 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADC800E58F -20240326215635 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADC9314DBF -20240326221037 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADCAE8162F -20240326225055 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADCFEC8FA3 -20240326225519 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADD072DFCF -20240326231305 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADD2AFDE1F -20240326233946 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADD60F026B -20240327001519 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADDA879EA3 -20240327002618 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADDBDFC89B -20240327003415 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADDCD9388B -20240327012525 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123BF06ED93 -20240327022256 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123C2EB1D03 -20240327025321 2 6 100 7679 5 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123C4EE6D8F -20240327031901 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123C6A6ECFB -20240327034252 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123C84AA3F3 -20240327034558 2 6 100 7679 5 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123C876E36F -20240327035607 2 6 100 7679 5 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123C91E770F -20240327043824 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123CBF90753 -20240327061734 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123D2A46DE3 -20240327071503 2 6 100 7679 5 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123D6765ED7 -20240327080706 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123D9FC24D3 -20240327091530 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123DE8C18AB -20240327092725 2 6 100 7679 5 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123DF4D10AF -20240327100400 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123E1BE884B -20240327102109 2 6 100 7679 5 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123E2D9E9AF -20240327111646 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123E69B7CAB -20240327140134 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123F1C97CDB -20240327144258 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123F48C6AEB -20240327150511 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123F6023BEB -20240327153839 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123F8480A9B -20240327160724 2 6 100 7679 5 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123FA2AE0EF -20240327170619 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123FE1F90CB -20240327201733 2 6 100 7679 5 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A541240B20240F -20240327202608 2 6 100 7679 5 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A541240BACBC77 -20240327204230 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A541240CCB39CB -20240327220340 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A5412412509EF3 -20240327230112 2 6 100 7679 5 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54124164279BF -20240327231350 2 6 100 7679 5 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A5412417159137 -20240328011850 2 6 100 7679 5 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A541241F8FAF0F -20240328020121 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A541242268881B -20240328020416 2 6 100 7679 5 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A5412422921477 -20240328035516 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A541242A164FCB -20240328051250 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCB60A9A5B -20240328061956 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCBA8EE4D3 -20240328083541 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCC39DE953 -20240328104001 2 6 100 7679 5 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCCBE8F2FF -20240328123936 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCD40450AB -20240328131851 2 6 100 7679 5 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCD6B3842F -20240328133514 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCD7C761BB -20240328163521 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCE3D44693 -20240328184556 2 6 100 7679 5 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCECA94E8F -20240328185443 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCED3C2EEB -20240328190404 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCEDD4DEAB -20240328193132 2 6 100 7679 5 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCEFA3B567 -20240328194029 2 6 100 7679 5 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCF039E777 -20240328205320 2 6 100 7679 5 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCF523DF3F -20240328210032 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCF59C775B -20240328221220 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCFA7B3FEB -20240328221329 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCFA863653 -20240328222505 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCFB420393 -20240328224858 2 6 100 7679 5 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCFCDA54CF -20240329004423 2 6 100 7679 5 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FD04B953EF -20240329024223 2 6 100 7679 5 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FD0BE0B937 -20240329035503 2 6 100 7679 5 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FD10BA6927 -20240329035634 2 6 100 7679 5 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FD10CC8C1F -20240329035914 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FD10F42063 -20240329045640 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FD14CA5323 -20240329050935 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FD159E9383 -20240329053141 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FD170D04C3 -20240329054343 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FD17D323FB -20240329062142 2 6 100 7679 5 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FD1A5DB2DF -20240329073301 2 6 100 7679 5 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FD1F20E86F -20240329074920 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FD20377F03 -20240329085033 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FD242F4BCB -20240329121808 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C124806CA43 -20240329122442 2 6 100 8191 5 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C12485AF08F -20240329153134 2 6 100 8191 5 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C1252D3F0CF -20240329155254 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C1254053513 -20240329161124 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C12550A7BDB -20240329161738 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C12555C651B -20240329174531 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C125A40EEC3 -20240329191732 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C125F71710B -20240329195323 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C126178458B -20240329204827 2 6 100 8191 5 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C12648DD15F -20240329234203 2 6 100 8191 5 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C126E5A5097 -20240329234306 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C126E615ACB -20240330005652 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C12726F6443 -20240330033619 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C127B69FC23 -20240330044619 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C127F446BC3 -20240330054010 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C1282492493 -20240330055823 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C128344D603 -20240330062335 2 6 100 8191 5 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C1284A06C1F -20240330082107 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C128B2D4E73 -20240330083555 2 6 100 8191 5 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C128BF7E127 -20240330084121 2 6 100 8191 5 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C128C3C894F -20240330104737 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C129350C1FB -20240330112334 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C12954A50B3 -20240330133619 2 6 100 8191 5 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C129CB0C66F -20240330135122 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C129D7F94B3 -20240330141203 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C129E9C046B -20240330155328 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C12A438CDC3 -20240330164337 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C12A6FF833B -20240330172236 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C12A9222D1B -20240330193325 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C12B07FB5BB -20240330201458 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C12B2CA43B3 -20240330212712 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C12B6C88EF3 -20240330225844 2 6 100 8191 5 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C12BBE67097 -20240331000148 2 6 100 8191 5 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B73EA509F -20240331002043 2 6 100 8191 5 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B74F19237 -20240331015303 2 6 100 8191 5 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B7A08A157 -20240331021926 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B7B77B293 -20240331031147 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B7E5DF07B -20240331032001 2 6 100 8191 5 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B7ECA5C3F -20240331054028 2 6 100 8191 5 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B86B76577 -20240331062300 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B891AC21B -20240331063150 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B898D590B -20240331064453 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B8A3FB29B -20240331070343 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B8B4728B3 -20240331082004 2 6 100 8191 5 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B8F78FC67 -20240331083046 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B90063753 -20240331085336 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B913BDDA3 -20240331104948 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B97AD8FBB -20240331121935 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B9CBCB66B -20240331125021 2 6 100 8191 5 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B9E75E9EF -20240331131006 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B9F876B2B -20240331135555 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BA21BA983 -20240331154257 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BA8151143 -20240331171643 2 6 100 8191 5 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BAD603A0F -20240331180835 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BB042B533 -20240331184114 2 6 100 8191 5 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BB20E55D7 -20240331190024 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BB31FB5FB -20240331193130 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BB4D5DEF3 -20240331203633 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BB878F90B -20240331215848 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BBD220A13 -20240331220718 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BBD9694FB -20240331234057 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BC2D1D8B3 -20240401015736 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BCA81EB2B -20240401044749 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BD41C3C93 -20240401051819 2 6 100 8191 5 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BD5D2C057 -20240401061504 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BD8EDA743 -20240401062619 2 6 100 8191 5 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BD98C438F -20240401095349 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BE51ECC83 -20240401133450 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BF189CF03 -20240401134927 2 6 100 8191 5 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BF2540457 +20250616002444 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626168803637 +20250616002455 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626168CECC1F +20250616002507 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA6261692C7353 +20250616002518 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA6261697DCA23 +20250616002520 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA6261698D69EF +20250616002525 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626169AA57DB +20250616002529 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626169CBB25F +20250616002546 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616A5307EB +20250616002549 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616A6385DB +20250616002603 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616AD0C40B +20250616002612 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616B10F7D3 +20250616002613 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616B182DC3 +20250616002615 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616B25024B +20250616002624 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616B689AFF +20250616002627 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616B79A1F3 +20250616002633 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616BA0CE7B +20250616002634 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616BA926E7 +20250616002638 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616BBF1327 +20250616002644 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616BEC119B +20250616002648 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616C0A4D47 +20250616002651 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616C1B6AAF +20250616002713 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616CCBE9D3 +20250616002747 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616DE70BB3 +20250616002755 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616E1C5B1F +20250616002802 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616E57586B +20250616002822 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616EFEC4AB +20250616002825 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616F0CBA83 +20250616002826 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616F133697 +20250616002834 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616F526313 +20250616002835 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616F56D8DB +20250616002838 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616F63E88B +20250616002842 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616F813C83 +20250616002843 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616F86C16B +20250616002854 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616FDC52CF +20250616002858 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62616FFB576F +20250616002914 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626170776DAF +20250616002919 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626170939C97 +20250616002920 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA6261709C6907 +20250616002954 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626171B2A95B +20250616002958 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626171CCCD77 +20250616003000 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626171D0FA13 +20250616003002 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626171E18997 +20250616003005 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626171EE92B7 +20250616003006 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626171F5ADB3 +20250616003007 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626171F9F0F3 +20250616003016 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA6261723F66A7 +20250616003019 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA6261724E9AAF +20250616003020 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626172573C83 +20250616003025 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626172798D8B +20250616003052 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA6261734F06E7 +20250616003103 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626173A507C3 +20250616003114 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626173FB9947 +20250616003118 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62617416E49B +20250616003127 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA6261745F914B +20250616003136 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626174A4F763 +20250616003143 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626174D621A7 +20250616003153 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626175244157 +20250616003155 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626175304CEB +20250616003159 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62617553F42F +20250616003209 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA6261759B7C0B +20250616003214 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626175BFA7AF +20250616003217 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626175D8110F +20250616003218 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626175D8BEBB +20250616003248 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626176C7670B +20250616003253 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626176E7934F +20250616003256 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626176FDC4CB +20250616003314 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA6261778C1A6B +20250616003318 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626177A40A3F +20250616003324 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626177CE451F +20250616003329 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626177F722EB +20250616003331 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626177FFB46F +20250616003336 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62617822C973 +20250616003337 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62617828C757 +20250616003405 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA6261790E9D67 +20250616003413 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA6261794E5533 +20250616003416 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA6261796529CF +20250616003430 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626179D66303 +20250616003432 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626179DCC057 +20250616003437 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62617A0363F3 +20250616003446 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62617A46B76B +20250616003455 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62617A8D28A7 +20250616003502 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62617AC41817 +20250616003503 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62617AC8EBC3 +20250616003509 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62617AF2AA53 +20250616003510 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62617AF70D8B +20250616003522 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62617B4FA6B7 +20250616003526 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62617B69E4D7 +20250616003530 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62617B8C1623 +20250616003541 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62617BE325B3 +20250616003554 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62617C48E047 +20250616003605 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62617C9BBBC7 +20250616003611 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62617CC7D78B +20250616003642 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62617DC7164F +20250616003645 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62617DDCEBBB +20250616003646 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62617DDD5EFF +20250616003700 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62617E532FAF +20250616003718 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62617EE49D4F +20250616003737 2 6 100 2047 5 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62617F78544F +20250616003745 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA62617FBBF7FB +20250616003759 2 6 100 2047 2 EE0FE3E5743174100BD44FCCF81A0B0C184789558AC0B35400ED73B9EFEEFFED3075997428479CAC425A827BBC69DB6C3DD2DFD508472073700893CE2B48F7A69CD9FB1D7C12FECB37E9A6928B3A3F80D1DBC0BAAB33AD37738E36CA83D3916529F1210294618DF754F1AD7BEA0A224CA3F771C18E2A9B9326F9AE725FFCCE244C2DA3435599DA41FF9C434DBB1302A6E9925E4F3BAAD3717288B312F1ACE0117E54AABAABFD113C3A722BBDCD26A7767371FF56CCD572A3F91006BE91C72B3FFEB235FAA91338B9A191845846FCEAFA179B059A13C158530E107E284E6CA2D63C002E2F6734CC9DBA05036F193D2D6F508CFCBA899512AD42CA626180295803 +20250616024900 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE52FE1D8983 +20250616024916 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE52FE5187AB +20250616025426 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE53015B738B +20250616025613 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5302B72663 +20250616025652 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE53032B6AB3 +20250616025739 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5303BCB52B +20250616025750 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5303D8B5E7 +20250616025804 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5303FF3613 +20250616025808 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5304041DF3 +20250616025813 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE53040D42B3 +20250616025942 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5305308573 +20250616025956 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5305566ACB +20250616030027 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5305B57B5B +20250616030040 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5305D951BB +20250616030126 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE53066DC43B +20250616030131 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5306792277 +20250616030407 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE53087BB3C3 +20250616030439 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5308DA22D7 +20250616030457 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE53090CC43F +20250616030623 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE530A10BF03 +20250616030625 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE530A12A4A3 +20250616030728 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE530AD1C937 +20250616030747 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE530B08F417 +20250616030753 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE530B149E1F +20250616030835 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE530B97C463 +20250616030917 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE530C17195B +20250616030941 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE530C5E29EB +20250616031012 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE530CB69887 +20250616031047 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE530D1B2B3B +20250616031102 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE530D42691B +20250616031119 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE530D6F09B7 +20250616031345 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE530F453A3F +20250616031437 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE530FE6A46F +20250616031522 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5310725CA3 +20250616031526 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5310796467 +20250616031630 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE531145D673 +20250616031744 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE53122DAB97 +20250616031748 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE531235DC5B +20250616031828 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5312B5048F +20250616031908 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE53132F33C7 +20250616031911 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE531334BD6B +20250616031947 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5313A1C823 +20250616032023 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE53140EA06B +20250616032050 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE531463930B +20250616032110 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE53149D1AE3 +20250616032205 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE53154763FB +20250616032225 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE531582AC17 +20250616032243 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5315B3627B +20250616032250 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5315C62473 +20250616032257 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5315D6A113 +20250616032301 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5315DA6E1B +20250616032456 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE53174EA23B +20250616032613 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5318454747 +20250616032619 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5318518CE3 +20250616032621 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE53185266F3 +20250616032705 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5318DB30D3 +20250616032722 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE53190CF753 +20250616032801 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE531983C403 +20250616032827 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5319D4832F +20250616032843 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE531A0401AB +20250616032854 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE531A1F94AB +20250616032858 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE531A26B47B +20250616032930 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE531A86BE9B +20250616032934 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE531A8B9B23 +20250616032956 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE531ACEECF7 +20250616033009 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE531AF0B31B +20250616033016 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE531B028B8B +20250616033036 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE531B3D86EB +20250616033049 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE531B65D127 +20250616033115 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE531BB41F3F +20250616033140 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE531C01336B +20250616033207 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE531C54135F +20250616033259 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE531CF6B74B +20250616033308 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE531D0E1EF3 +20250616033331 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE531D5478CB +20250616033419 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE531DED6323 +20250616033601 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE531F31D043 +20250616033611 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE531F48BD03 +20250616033701 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE531FEA1EFF +20250616033825 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5320F3FBAB +20250616033938 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5321DD2153 +20250616033959 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE53221A5443 +20250616034137 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE532357E1EF +20250616034150 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE53237AE35B +20250616034211 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5323B7E21F +20250616034317 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE532486893F +20250616034324 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE532496A2F7 +20250616034453 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5325B5FF2F +20250616034508 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5325DFBD83 +20250616034516 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5325F4BEAF +20250616034538 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE532632A773 +20250616034604 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE53267F3C1F +20250616034646 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE532703CCAF +20250616034920 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE5328EDA0EF +20250616035201 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE532AF8A223 +20250616035247 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE532B864D0B +20250616035259 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE532BA3AD6F +20250616035343 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE532C2F66F3 +20250616035404 2 6 100 3071 5 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE532C6CBB1F +20250616035550 2 6 100 3071 2 CEDC89F91D5B5F3DAC95CBCC930B48068AE6149F5DC88374E503625E4B5236F2C65319DAD0D0B6A82BF7F41B255248306E71D51F9E2869885B39DACBD5222ACDFDDF290C21129701015D6F2AFED9904454BA15479CC4E819311C27F83CAAB9C8C4B3572489C94167DF92ABDEBD8D738411446904D2FDC1C02A38320CC5FA7EFAD66C787B5D76754F9858490E0CEB18DB7845B8C685D78414BE438E08FE7151AF55E234E9808986E342B8ADD40797D4EE8453C5F18A1AADCF026E6A148BAFC2874A8BEBA0E675861B3EC122FB3A0ECAB6BBA1B322D86026F843B459B8B89423117C7FFC47A922EF3AA3C3EA40885D9F2E94D6E87C0C578655F38FC53389B5356DE343BD142253CEBCAFC014D1F22B6F50018BEA27F05DB691B65C10C4F3C7E23E860D537276851B30257F206233CA2F67E6F96D2BBE5C58A22ADF5F84E804273E3B6B4A7B57F78324A3ACCCA14F9F5F2E1C6E24B20CBB1DF11A6C7B64DE5AA16E460C646507CD5BA015ECAB525DE328579EF6E20EFF8829E31049AE532DC5FC83 +20250616025251 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D0AAACEB7 +20250616025500 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D0B703A67 +20250616025644 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D0C098BAF +20250616025822 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D0C9F6593 +20250616025947 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D0D1C3E97 +20250616030000 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D0D2AE36B +20250616030055 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D0D7B87EB +20250616030200 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D0DD7FA2B +20250616030339 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D0E70A8D7 +20250616031225 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D119395BB +20250616031921 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D141530E7 +20250616032156 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D14FF9A9B +20250616032638 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D16BBC31B +20250616032926 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D17C00207 +20250616032959 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D17ED9CB7 +20250616033143 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D188B3F2B +20250616033239 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D18D93D7B +20250616033406 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D195811AF +20250616033432 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D197A3F23 +20250616033615 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D1A164913 +20250616033743 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D1A9B44E3 +20250616034059 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D1BCEF6E7 +20250616034148 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D1C136A53 +20250616034236 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D1C5441E3 +20250616034337 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D1CAB3D9F +20250616034506 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D1D3741AB +20250616034604 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D1D8D2B83 +20250616034629 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D1DABAEFF +20250616034737 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D1E0E748B +20250616034755 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D1E214BBF +20250616034809 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D1E33125F +20250616035026 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D1F01594F +20250616035037 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D1F0BD763 +20250616035313 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D1FFD9B1F +20250616035402 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D2044014B +20250616035437 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D20733A13 +20250616035449 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D207F63BF +20250616035530 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D20B97BAF +20250616035709 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D214FA723 +20250616035859 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D21FB8CD3 +20250616035947 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D22419713 +20250616040250 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D23574D73 +20250616041101 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D265B4043 +20250616041134 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D2688243B +20250616041233 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D26E075D3 +20250616041313 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D2717FB07 +20250616041513 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D27C50567 +20250616041521 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D27C7F1FF +20250616041543 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D27E425BB +20250616041613 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D280BE63F +20250616041750 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D289E2F63 +20250616041811 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D28B7A6AB +20250616042211 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D2A30F7BB +20250616042216 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D2A31526F +20250616042440 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D2B142177 +20250616042937 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D2CF2463F +20250616043203 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D2DCED4A3 +20250616044015 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D30DE8723 +20250616044102 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D3123CD73 +20250616044318 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D31EC950F +20250616044447 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D326D5903 +20250616044737 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D33780D73 +20250616045055 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D34ADF7BB +20250616045513 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D363FBDB3 +20250616045709 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D36F8CB13 +20250616045917 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D37C1BF97 +20250616050232 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D38EF2887 +20250616050404 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D3978CA43 +20250616050547 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D3A18F2FB +20250616050558 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D3A207793 +20250616050630 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D3A4A78B3 +20250616051043 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D3BCF05C7 +20250616051341 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D3CE19A73 +20250616051541 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D3D96A783 +20250616051610 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D3DBD0F4F +20250616051630 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D3DD597C3 +20250616052534 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D412B8027 +20250616052644 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D4191D41B +20250616052653 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D4197FE0F +20250616053049 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D43097AFB +20250616053247 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D43BB9F6F +20250616053318 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D43E4F583 +20250616053536 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D44B73D53 +20250616053606 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D44E1EE3B +20250616053755 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D45876E0F +20250616054222 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D4726EF6B +20250616054241 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D473B5563 +20250616054858 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D498E3BAF +20250616054917 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D49A569F7 +20250616055026 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D4A0F8DAB +20250616055148 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D4A8B902F +20250616055232 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D4AC9177F +20250616055323 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D4B1157AB +20250616055559 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D4C06056B +20250616055943 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D4D5F3253 +20250616060324 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D4EB4258B +20250616060456 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D4F406FC3 +20250616061112 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D51930143 +20250616061754 2 6 100 4095 2 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D5404A0F3 +20250616062045 2 6 100 4095 5 ECFE2345925613E912C05977A53B7FFB53C9CC5F153ABC4B86FB6EE484FCA6EFA4FB6A21A07984A885B16B8316BD30007D0AEB805E960C0BDEB0AC4D7941E9299071B2FD8E29936EEF604963DAFF758B79326DBA0F875C5A1BA26AA7841135758235A4359130BA4B50FD05921D6FCE4CB46FC7DCCF7374DF61ADFEE13BCBA269AD82F379279EE9DA30F1ECBC59DA3EE072F08E278ED59107BB38429BD020383A1316B5B6505D98D4DE55935F8AB9D65316491BE5E104CF7B004878D04D839278D373C65211EA91E774246B33F98066C95B959127EB03D9B0C4BFB141E61E0C57741E18A1D69DABE678FFBDAF384FC7E8546CB032DEA833E4FAF2A2BB965364566AD5591E56FB54C6CF10D4DBB0C0B01EA5EE17043A8B033BF3C0209EAA6CADD9CECCA503F6DF31382411C32100DC16D2C92682A0EA02CABB44ED418BC92D906343799C77AEA661123BB1A304ED9CAAB8CF2D27FAEADB5B723562B164C0C7636EEA2C70A2544967B5087CBBE6EEB7B69B7CF00E45543FC6A5E611A0476D310EFB400FD7280CB984C4F61A808311351C685957BD311052FE647A84F82EDFC9FC0F8A7ABDA3ACB06084EA82B761F99FE4A5DA7C6E95C4346447A3BC816C29734DFABE2451087D44A605365B38F19F8C47581E0415D7CB67F2FF045AB8C6F4589768E065CB5611C93FD7D10FC57C082B7A7D6FFBC9733264354EB8AB2F1D550D543F +20250616031848 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABCFEBCFD5B +20250616041123 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD054A326B +20250616042441 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD06E7D59B +20250616042612 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD07106BD3 +20250616043534 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD08355803 +20250616043924 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD08A63293 +20250616044633 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD0982DEEB +20250616045128 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD0A19FE5B +20250616050534 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD0BD5F123 +20250616051248 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD0CB284DF +20250616051744 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD0D4576E7 +20250616052615 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD0E4EAA4F +20250616053024 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD0EC9F933 +20250616054931 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD112C869B +20250616061023 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD13C0FA33 +20250616061103 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD13CF073F +20250616062941 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD16121F27 +20250616063708 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD16F3763F +20250616065251 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD18E600CF +20250616065656 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD1961739B +20250616070508 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD1A63040B +20250616071147 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD1B2EB503 +20250616072730 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD1D19F2FF +20250616075823 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD20E7E04F +20250616085003 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD274EB153 +20250616090823 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD298EF107 +20250616090942 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD29B0BD37 +20250616091953 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD2AD9C44B +20250616092428 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD2B623263 +20250616092837 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD2BDBD627 +20250616093520 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD2CA7968B +20250616093745 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD2CEA82B3 +20250616100958 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD30DEC413 +20250616104346 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD34EE8193 +20250616104422 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD34F86857 +20250616111013 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD3825D493 +20250616113910 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD3BAD9997 +20250616115912 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD3E1DEE1B +20250616121039 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD3F7A2C5B +20250616130700 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD46657F43 +20250616131547 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD47787287 +20250616131819 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD47C09A53 +20250616132017 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD47F6C84F +20250616140437 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD4D750693 +20250616141233 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD4E6BD827 +20250616141414 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD4E9887C3 +20250616141602 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD4EC7148F +20250616142052 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD4F592B73 +20250616142305 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD4F9896B3 +20250616151719 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD5631119F +20250616152331 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD56EC431B +20250616154044 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD590666B7 +20250616155712 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD5B10CB97 +20250616160048 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD5B7B673F +20250616170503 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD6377E0DF +20250616170926 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD63FDBC83 +20250616171549 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD64C3C247 +20250616171931 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD653018DB +20250616175241 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD69541097 +20250616183731 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD6EE1B19F +20250616184010 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD6F2D909B +20250616184304 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD6F839987 +20250616190140 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD71C69267 +20250616190401 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD720797DB +20250616191520 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD73692CE3 +20250616192842 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD75053C7B +20250616194857 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD7782C27B +20250616195918 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD78C5964B +20250616200557 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD799219DF +20250616203649 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD7D732CE7 +20250616205237 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD7F5D63A3 +20250616211219 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD81D243C7 +20250616211808 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD827D9623 +20250616213202 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD8429B4CF +20250616214429 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD85BA7CCF +20250616215347 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD86DADC7B +20250616215504 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD86FBFAC3 +20250616215846 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD876E6177 +20250616221047 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD88DF6D3B +20250616223829 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD8C566667 +20250616224259 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD8CE0DE5B +20250616231230 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD908DA493 +20250616232834 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD928EEF7B +20250616233319 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD931E7A6F +20250616235722 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD961D984F +20250617002544 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD3F7A2C5B +20250617012034 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD46657F43 +20250617012906 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD47787287 +20250617013133 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD47C09A53 +20250617013329 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD47F6C84F +20250617021654 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD4D750693 +20250617022440 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD4E6BD827 +20250617022615 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD4E9887C3 +20250617022801 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD4EC7148F +20250617023244 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD4F592B73 +20250617023455 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD4F9896B3 +20250617032739 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD5631119F +20250617033339 2 6 100 6143 2 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD56EC431B +20250617035013 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD590666B7 +20250617040630 2 6 100 6143 5 E14CB0AD6B03109962790668D317CC69BC29BB96941F75C9BB739C214F83ABACC6508E89C92108C3C075AC60830A996E6A5758E76CCE93C18627A18E951FF26DD53CB94D1348BD062C835177EF5B07353F9AC7D5874D78B3E215C4DC54A8E8F0A3D97705390A53050F25C75E944A4AF84803830492006104387892A78ABBCE80E7950A1B4F59D79AD867DF6DCFD7E23046774C0E28FD907F37F5EE9EF6D9F593DF94313E725D9EE35C57DBE177FA3027AE4BF30C4509333CCBE98DF2E251710A4B899C6C42CA499A8D2657FDC1A82945C74776AC859665175FD8F1DCB16C7B22D455E584DB02B3A95AF9A88126CE3634570A6968DB2654254A030B2F8A133E49F6EAFCD8015FF22D7C622026D6D6FA63BEFA7237C5EC05B7DF99A5854D4792683B454F0ECD52EF41266A550595594556AE969EE307915AC40FA9C551379F2C485A1D53F9C960CF9262A8AD681CFF53EE2D0E208E3DDAFC7C6C82271E0890745579C906BA77716E593D29C5B15F0C18E616BCA698BE676918697281730E0DAF112EE5B763906FC0A373EC15915202FB96241F26AAB0D77DA4357CB2B0C3101F3DB88B5D3AB4497C21377DD543BB422C12CF4E18861AE40924DC2D9AFCCDA500FCFA693288B5DD73216515ECCB12D0400D19BB27E50D3C3183BEA9C113B5A553F9704962FD4BC8510D930F32061EABEC7FC2C1CE32CA6297F5BA8DB6E4B6AEB755A07EF153C51BF7C07A827F43FBFDD4D5136187533FB6155535A9369C5776BDB22D1BE141316CA5DF6704FF2F970C070F6EA37678258683DEDF45056F127C5819E59F2A94680CF651EA983632EA91F47BF80B6D725ADD1E5795884239C5877E753C374266DFD973C414587074750852A5397A7FAC047152100F29AF82E7B2DA89DF3248CAA2B3DF71C4912989A4A660F8DF46155229B4AAF59789ACF49B0021CF015C59D97DE13B91EEA8BFAD9CA6699C59CF385C40F9FC38263207A46505D76DE443A3C2A7BEFB5E5A1040337F50D569F529D885CD651A87100B4634EE7A6F0D5C607E894E1475434F56DC62B016C73C07AE7A716B55F0AD0F399ABD5B10CB97 +20250616035607 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85826297803B +20250616042133 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582643F4617 +20250616052001 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A858268210533 +20250616054850 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85826A097C53 +20250616080903 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A858273567FDB +20250616093015 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A858278B0E5BB +20250616103728 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85827D1D4113 +20250616111218 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85827F657FAB +20250616112833 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A858280648FFB +20250616125341 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A858285F47EEF +20250616135204 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A858289C8483F +20250616150327 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85828E80E33B +20250616161704 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582936A88E3 +20250616170843 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A858296D09663 +20250616174557 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A858299434467 +20250616185934 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85829E1EAFA3 +20250616190202 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85829E3F6D2B +20250616202814 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582A400B97B +20250616210901 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582A6B686D7 +20250616212925 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582A805594B +20250616232503 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582AFB7787B +20250616235406 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582B19E791F +20250616235513 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582B1A8E57B +20250617002853 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A858289C8483F +20250617013846 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85828E80E33B +20250617025103 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582936A88E3 +20250617034223 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A858296D09663 +20250617041923 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A858299434467 +20250617053144 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85829E1EAFA3 +20250617053409 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85829E3F6D2B +20250617075210 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85826297803B +20250617081717 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582643F4617 +20250617091509 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A858268210533 +20250617094347 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85826A097C53 +20250617120252 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A858273567FDB +20250617132226 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A858278B0E5BB +20250617142749 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85827D1D4113 +20250617150158 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85827F657FAB +20250617151822 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A858280648FFB +20250617164140 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A858285F47EEF +20250617173833 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A858289C8483F +20250617184837 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85828E80E33B +20250617200056 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582936A88E3 +20250617205150 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A858296D09663 +20250617212820 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A858299434467 +20250617223953 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85829E1EAFA3 +20250617224217 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85829E3F6D2B +20250618000646 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582A400B97B +20250618004650 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582A6B686D7 +20250618010652 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582A805594B +20250618030037 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582AFB7787B +20250618032918 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582B19E791F +20250618033024 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582B1A8E57B +20250618042330 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582B53C775B +20250618045322 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582B7440A97 +20250618052359 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582B954EBF7 +20250618055947 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582BBB8C053 +20250618070614 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582C035FFE3 +20250618072936 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582C1B7AD67 +20250618073924 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582C2551963 +20250618081151 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582C480076F +20250618091411 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582C8B7648B +20250618104754 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582CEFBD56F +20250618114039 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582D2828D6F +20250618121547 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582D4D953FB +20250618122123 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582D533E9B3 +20250618123407 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582D608F5D7 +20250618124634 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582D6DB3867 +20250618125907 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582D7B0E9A3 +20250618131722 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582D8E5433B +20250618154711 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582E318E597 +20250618161518 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582E4FC61FF +20250618173320 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582EA4C196B +20250618181001 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582ECCDA5AF +20250618182405 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582EDB674CF +20250618185052 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582EF76E9A7 +20250618205008 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582F7986EE3 +20250618212939 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8582FA3E17BF +20250618235642 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A858304421B3B +20250619002145 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A858305ECDC73 +20250619004148 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8583074F20CB +20250619005851 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A858308581EC3 +20250619011346 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A858309471D47 +20250619020628 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85830CCF0183 +20250619024424 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85830F5F31F3 +20250619033602 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A858312D48B7B +20250619043748 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A858316F99C53 +20250619050309 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A858318AA26EF +20250619053830 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85831AFC8263 +20250619063025 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85831E74A76B +20250619063819 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85831EF74217 +20250619064710 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85831F833663 +20250619082314 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8583253C251F +20250619082850 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8583257F0853 +20250619090252 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A8583276E0493 +20250619095319 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85832AA1D0AB +20250619111645 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85833035388F +20250619143826 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85833DC506AB +20250619144408 2 6 100 7679 5 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85833E1EBFA7 +20250619144618 2 6 100 7679 2 EEB5FE98B7CF15B438162A5F2DEBBAB8BCF08B8A2614E263AA570052D2B01AC3E0B943491218DF247DB063E7DAECD19D0CD00C65335041AC9D3E4B8493CB58F9CBB166E38FF5E8697EF59D9EE4FAC6415070E0156AF8DA6BE11D672AA9A8E71033936AF75D835CCDBB0ED13CB17CBF9C9D98DEB4FAAD874FCD0929E86CF411426A3A96CED22F7EDC5F7E8D3A3B860F91E3FE92623F97C15EF13921C6AE6B3A566C7E42F46EF7B9721A09D10BEE52CE93694F6EF85F362D90239C4066C8FFFA6C6CCBAF59DFE083B248BF313F2A9D3EF96ACF569CA1B05FBDEFBD4A52C854C7B71AAB2B8AEAF8BFA8F283851E4CAA76F7D155939555F09830E49F38E73A7AE48B489883CA0D96A59B3560A8DF02DC0A0E5B6AD0AFD445B54F5580F4D962D8156DB6A0F70E5E4E47CF3CF9E1281180F5BC90B5C6FCB2DEFF1BD985D405BC3A138700D75D9BAEBBD1A7496F5CD1E6E6D5C0325B89E120A0994AFF0F35741DDC17A7D7C19A818A6C3DB5874B0E78B2BA319C6D4F850762EC32005074492723FAD2876E1C8F9A318852E97F6B28706F67ACAB944E8CFCA7C6A47C0D2F9B6907713CFFE21DEB070F45BAC19828094C424A445440ADF79E925BFE0BE687E82751D9ACBDDA02A6FACD4FEC77EEB9CD32A265B67ABFF9CF22E7EE68DCA133109BD7515B0002A9D4DEF5E3B190CE0E5C8EE2BF18F6176CD47DC00C87CD5CFBADC9D3085DAE39ECC4B320C4AE130E62A03FA4E321F0CDA4844551140DAB5658F27B2A1884BA1B039F25AA1E386BBE9C0BB3906880E46A22D2F9F9C1A7943BC1D71E45A9E6FF4828196192B4063650EAC50555E53516BF4D816888C1E7841914862FA5F82181204155ADCD7652D4B3F8CB0CDFF69BC897FEE50C420A6243059B742171BBC5C94BC6AF23AE90F0DE756DBC1027E3F92EE866A669054CC133A685AE21A51478A305851308220705E0E38D97BD62A8B07047594266DEE3414D3D6C0659C4A8DB9484B86E0638ED13499E7B58030881991FD4E83B61AD429E4276DE69DB74677F16A1EB6D5D3756CB7074B312DDA5679C4E85720ECA7B738F4556BCAADD307D4A2F29158CE326F55CCDEB8755BABC2F7F8DE3F8B19C786D4219E9C45CB9FC7BAD2C5EE5984A392E2AC541662C4552CDB981BB65FE4A28FD19B1A472015BB45AB351F0CF6A9FD756EF6471794E08AB5A7092E0657F873133A0FEB2882251B80D08FC475EB43173F6A9F34787A67B282BB86FB559D883FDE93F10CCA73EA0ECC232CA1B719A98E0280CEAC5338550DBAE750E388F6671F8552A4FEFEDA1190DA60909A797336785C8C7BE9C233CC33F86818D1686C9558C900553F19A85833E3B9B63 +20250616030759 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F355CA78B +20250616040000 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F3838355B +20250616041144 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F38D7F49B +20250616050424 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F3BBD0A5B +20250616052304 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F3CBEA257 +20250616061654 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F3FACE56B +20250616075926 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F454D7B5F +20250616081144 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F45F6C43F +20250616090044 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F48A7A38B +20250616122407 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F53BFE9BB +20250616142400 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F5A4DBBAF +20250616160108 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F5F8C5217 +20250616193743 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F6B909527 +20250616213952 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F72566C2F +20250616232936 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F785F050F +20250617022031 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F5A4DBBAF +20250617035521 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F5F8C5217 +20250617084531 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F5A4DBBAF +20250617102034 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F5F8C5217 +20250617135507 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F6B909527 +20250617155752 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F72566C2F +20250617174609 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F785F050F +20250617185010 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F7BE9453B +20250617203518 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F81D8D1BF +20250617221016 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F872F0C47 +20250617224617 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F89296483 +20250618022226 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F955CABCF +20250618025323 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F971B858F +20250618025845 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F976024CF +20250618031117 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F980C128F +20250618050316 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93F9E572DB3 +20250618054129 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FA0770223 +20250618054813 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FA0D14BEB +20250618061719 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FA267BBE3 +20250618064955 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FA436E453 +20250618065418 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FA46BE9D3 +20250618091516 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FAC5A7C77 +20250618094924 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FAE3F83CB +20250618115905 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FB57652DF +20250618130037 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FB8EDA617 +20250618132027 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FBA050653 +20250618141430 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FBD161D4F +20250618141922 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FBD51B563 +20250618142521 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FBD9DAAA3 +20250618155406 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FC2A05D13 +20250618171641 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FC74EF183 +20250618171856 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FC769295B +20250618181022 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FCA4F6A13 +20250618202914 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FD226B033 +20250618220927 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FD7DA67EF +20250618224256 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FD9B5DB6B +20250618232600 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FDC16AAB7 +20250618232719 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FDC210A83 +20250618233147 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FDC59DC33 +20250618234218 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FDCEE4BE3 +20250618235527 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FDDA3E65F +20250619001532 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FDEC67F03 +20250619021548 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FE56B64F3 +20250619022245 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FE5CF6A53 +20250619050955 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FEF3B127B +20250619055851 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FF1FBE17F +20250619061510 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FF2DEEC33 +20250619062630 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FF376CBEB +20250619062934 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FF39994E7 +20250619075919 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FF8440A8F +20250619100929 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED93FFEB8B7A3 +20250619113103 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED940033A057B +20250619121235 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED94005794C2F +20250619123456 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED94006B2B897 +20250619124527 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED94007401FAB +20250619143042 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED9400D0E145B +20250619161110 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED94012944667 +20250619180616 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED94019090B9F +20250619182713 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED9401A2D7303 +20250619200425 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED9401F9624E3 +20250619202406 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED94020A68B53 +20250619224804 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED94028B6619B +20250619234955 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED9402C389D97 +20250619235705 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED9402C96896B +20250620000401 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED9402CF2980F +20250620001146 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED9402D572997 +20250620002229 2 6 100 8191 5 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED9402DE7288F +20250620004426 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED9402F1E827B +20250620013315 2 6 100 8191 2 DA1E367F51064DE37C61DF292F64D691D584C03B41D0D878E4EAA25ECE0D922818300E39D15F259EB25F466620B3BAA5A1BB314488CD6BC2BA17B82542CE832E02410CEB2C6619BD5358D1C0898F91777C76CE47507DAC5DCE417ED74BD7D816447C06A59051E5F70EEEF96BEBFC70752E26A3507DE5B89B66548A4AC87BA678064ECC851356306BAC0AF3189C284C5D2AE4E624552B2DC83705CB320D3AD9445D569486A6B80B05BBD2C55E8E085A25F422F2FACF52B33ECCA626BE5EC2283FF401D937B3FBE49527D233C8E7187E0A85AC04871CCE580067BDD5C687285C5DA0A930B05AF96DD44CA6F2935C7398251CA9DB735069F88DE6CE2423B6A334DA2CC50AFD2A29C1B5CA7785CCEFD856B39B87666AE368996CEBCC3999562434DA299C1856EDED42DF3F92B122957175296F115C0D6FB214B13EA5616DC9597768FBFF08E2B6BAF5619C078E11F7EEFD8C90459F155305DA5854EE326490AA8D6A9403A62031E890881AD2FDF1855A7BBD6591AD2D1C85EF1270BD1EAFC5EF58336EF37155421222DE87045709F2590250E6CB893DA415E0C1ECFD856544C1100EC71541721C6632CF5A2698A4F8A831414D9DF21B5DB664FCE613BE362C2851DFA14997AF54C9DE6EC79A402060A379C2706BBCE05D192FEDF9C3E6838E6D7B5B8B16D08AE01A5A614CD41CDC6D2EF81CAB6A6C66F2DFE62DFF99F50BBD74E2D1C6F301F84F8DE83952023A2B06FA5391082EF6A4AC7DBFEBB48F0572B6C08FD390EF30D75B6E442D273A6C248A49CE291B55B7E820685541EEE2AA7EBAFAA9516A5EFAB4F41F81347829956522C44DAAC5727E7BFD9DE81493069497D3092E4F36597EE35142629CB3B64750964CEFAB2916B51C507C48DEB6DC62681ED8AEB4F29A3D82D2C20C54153C874F090C9DB8112A6F4F279E22D6CF17C6230963B7A46AFA77195B4CB982D00F351BE4ACBF3B721EF95CDEEF56A3DFF16503BC9B1D1094131DD3CE3DEED0F579EBDD35308FCEB3877F06AE591875236F79608699CBA67B50D6540955D5BEE1CD0A24C175056ABE9C3A93E6EEECD21B60E8BD2F4E73C7385BC35F210E4E29AD2D957008C9BC985B5AB5942E506C3EA2C66BED0811BED5D7CC8CAC13AF701555F6C3E36A21C5BE052E01916B3A22D315ED4824F310D540AD1FBE4A2EF695F507175B4B91D0B3E8C970038700BB5147FC461641858AE21BEB4DDA61A7BE98419001223F4754A4A67CEE4683DDC1094BC2843ED5C95A4769C85450141E1EADF6A611D5E9B8C3A621D94BE0E2965F8309CDDEE5BDDACF9BA41097CBF50144E5E50BF17BE66C8C5F201B007BE42D52A7B65A37E288AC425AC7FD16D059B95EA1EDFFD361F717FEA5F1586459FF2218652DAFB69511B3551CCEF1417ED578B083C92C58AAEF2BE45C24A9877E2261E51A26D69ED94031D70FAB diff --git a/moduli.0 b/moduli.0 index f72ca52..3c3c81b 100644 --- a/moduli.0 +++ b/moduli.0 @@ -71,4 +71,4 @@ STANDARDS M. Friedl, N. Provos, and W. Simpson, Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer Protocol, RFC 4419, March 2006. -OpenBSD 7.6 April 16, 2022 OpenBSD 7.6 +OpenBSD 7.8 April 16, 2022 MODULI(5) diff --git a/moduli.c b/moduli.c index 481ca2a..e8ef963 100644 --- a/moduli.c +++ b/moduli.c @@ -1,4 +1,4 @@ -/* $OpenBSD: moduli.c,v 1.39 2023/03/02 06:41:56 dtucker Exp $ */ +/* $OpenBSD: moduli.c,v 1.41 2026/03/03 09:57:25 dtucker Exp $ */ /* * Copyright 1994 Phil Karn * Copyright 1996-1998, 2003 William Allen Simpson @@ -87,13 +87,6 @@ #define SHIFT_MEGABYTE (20) #define SHIFT_MEGAWORD (SHIFT_MEGABYTE-SHIFT_BYTE) -/* - * Using virtual memory can cause thrashing. This should be the largest - * number that is supported without a large amount of disk activity -- - * that would increase the run time from hours to days or weeks! - */ -#define LARGE_MINIMUM (8UL) /* megabytes */ - /* * Do not increase this number beyond the unsigned integer bit size. * Due to a multiple of 4, it must be LESS than 128 (yielding 2**30 bits). @@ -132,26 +125,26 @@ */ /* sieve 2**16 */ -static u_int32_t *TinySieve, tinybits; +static uint32_t *TinySieve, tinybits; /* sieve 2**30 in 2**16 parts */ -static u_int32_t *SmallSieve, smallbits, smallbase; +static uint32_t *SmallSieve, smallbits, smallbase; /* sieve relative to the initial value */ -static u_int32_t *LargeSieve, largewords, largetries, largenumbers; -static u_int32_t largebits, largememory; /* megabytes */ +static uint32_t *LargeSieve, largewords, largetries, largenumbers; +static uint32_t largebits, largememory; /* megabytes */ static BIGNUM *largebase; -int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *); -int prime_test(FILE *, FILE *, u_int32_t, u_int32_t, char *, unsigned long, +int gen_candidates(FILE *, uint32_t, BIGNUM *); +int prime_test(FILE *, FILE *, uint32_t, uint32_t, char *, unsigned long, unsigned long); /* * print moduli out in consistent form, */ static int -qfileout(FILE * ofile, u_int32_t otype, u_int32_t otests, u_int32_t otries, - u_int32_t osize, u_int32_t ogenerator, BIGNUM * omodulus) +qfileout(FILE * ofile, uint32_t otype, uint32_t otests, uint32_t otries, + uint32_t osize, uint32_t ogenerator, BIGNUM * omodulus) { struct tm *gtm; time_t time_now; @@ -184,9 +177,9 @@ qfileout(FILE * ofile, u_int32_t otype, u_int32_t otests, u_int32_t otries, ** Sieve p's and q's with small factors */ static void -sieve_large(u_int32_t s32) +sieve_large(uint32_t s32) { - u_int64_t r, u, s = s32; + uint64_t r, u, s = s32; debug3("sieve_large %u", s32); largetries++; @@ -242,25 +235,16 @@ sieve_large(u_int32_t s32) * The list is checked against small known primes (less than 2**30). */ int -gen_candidates(FILE *out, u_int32_t memory, u_int32_t power, BIGNUM *start) +gen_candidates(FILE *out, uint32_t power, BIGNUM *start) { BIGNUM *q; - u_int32_t j, r, s, t; - u_int32_t smallwords = TINY_NUMBER >> 6; - u_int32_t tinywords = TINY_NUMBER >> 6; + uint32_t j, r, s, t; + uint32_t smallwords = TINY_NUMBER >> 6; + uint32_t tinywords = TINY_NUMBER >> 6; time_t time_start, time_stop; - u_int32_t i; + uint32_t i; int ret = 0; - largememory = memory; - - if (memory != 0 && - (memory < LARGE_MINIMUM || memory > LARGE_MAXIMUM)) { - error("Invalid memory amount (min %ld, max %ld)", - LARGE_MINIMUM, LARGE_MAXIMUM); - return (-1); - } - /* * Set power to the length in bits of the prime to be generated. * This is changed to 1 less than the desired safe prime moduli p. @@ -274,46 +258,17 @@ gen_candidates(FILE *out, u_int32_t memory, u_int32_t power, BIGNUM *start) } power--; /* decrement before squaring */ - /* - * The density of ordinary primes is on the order of 1/bits, so the - * density of safe primes should be about (1/bits)**2. Set test range - * to something well above bits**2 to be reasonably sure (but not - * guaranteed) of catching at least one safe prime. - */ - largewords = ((power * power) >> (SHIFT_WORD - TEST_POWER)); - - /* - * Need idea of how much memory is available. We don't have to use all - * of it. - */ - if (largememory > LARGE_MAXIMUM) { - logit("Limited memory: %u MB; limit %lu MB", - largememory, LARGE_MAXIMUM); - largememory = LARGE_MAXIMUM; - } + /* Always use the maximum amount of memory supported by the algorithm. */ + largememory = LARGE_MAXIMUM; + largewords = (largememory << SHIFT_MEGAWORD); - if (largewords <= (largememory << SHIFT_MEGAWORD)) { - logit("Increased memory: %u MB; need %u bytes", - largememory, (largewords << SHIFT_BYTE)); - largewords = (largememory << SHIFT_MEGAWORD); - } else if (largememory > 0) { - logit("Decreased memory: %u MB; want %u bytes", - largememory, (largewords << SHIFT_BYTE)); - largewords = (largememory << SHIFT_MEGAWORD); - } - - TinySieve = xcalloc(tinywords, sizeof(u_int32_t)); + TinySieve = xcalloc(tinywords, sizeof(uint32_t)); tinybits = tinywords << SHIFT_WORD; - SmallSieve = xcalloc(smallwords, sizeof(u_int32_t)); + SmallSieve = xcalloc(smallwords, sizeof(uint32_t)); smallbits = smallwords << SHIFT_WORD; - /* - * dynamically determine available memory - */ - while ((LargeSieve = calloc(largewords, sizeof(u_int32_t))) == NULL) - largewords -= (1L << (SHIFT_MEGAWORD - 2)); /* 1/4 MB chunks */ - + LargeSieve = xcalloc(largewords, sizeof(uint32_t)); largebits = largewords << SHIFT_WORD; largenumbers = largebits * 2; /* even numbers excluded */ @@ -448,7 +403,7 @@ gen_candidates(FILE *out, u_int32_t memory, u_int32_t power, BIGNUM *start) } static void -write_checkpoint(char *cpfile, u_int32_t lineno) +write_checkpoint(char *cpfile, uint32_t lineno) { FILE *fp; char tmp[PATH_MAX]; @@ -577,13 +532,13 @@ print_progress(unsigned long start_lineno, unsigned long current_lineno, * The result is a list of so-call "safe" primes */ int -prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted, +prime_test(FILE *in, FILE *out, uint32_t trials, uint32_t generator_wanted, char *checkpoint_file, unsigned long start_lineno, unsigned long num_lines) { BIGNUM *q, *p, *a; char *cp, *lp; - u_int32_t count_in = 0, count_out = 0, count_possible = 0; - u_int32_t generator_known, in_tests, in_tries, in_type, in_size; + uint32_t count_in = 0, count_out = 0, count_possible = 0; + uint32_t generator_known, in_tests, in_tries, in_type, in_size; unsigned long last_processed = 0, end_lineno; time_t time_start, time_stop; int res, is_prime; @@ -698,7 +653,7 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted, * due to earlier inconsistencies in interpretation, check * the proposed bit size. */ - if ((u_int32_t)BN_num_bits(p) != (in_size + 1)) { + if ((uint32_t)BN_num_bits(p) != (in_size + 1)) { debug2("%10u: bit size %u mismatch", count_in, in_size); continue; } @@ -719,7 +674,7 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted, if (BN_mod_word(p, 24) == 11) generator_known = 2; else { - u_int32_t r = BN_mod_word(p, 10); + uint32_t r = BN_mod_word(p, 10); if (r == 3 || r == 7) generator_known = 5; diff --git a/monitor.c b/monitor.c index 5966b4f..9d6672b 100644 --- a/monitor.c +++ b/monitor.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.c,v 1.244 2024/09/15 01:09:40 djm Exp $ */ +/* $OpenBSD: monitor.c,v 1.255 2026/03/28 05:06:16 djm Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -28,39 +28,29 @@ #include "includes.h" #include -#include #include +#include +#include +#include #include #include #include -#ifdef HAVE_PATHS_H #include -#endif +#include #include #include -#ifdef HAVE_STDINT_H -# include -#endif -#include -#include #include +#include #include +#include +#include #include -#ifdef HAVE_POLL_H -#include -#else -# ifdef HAVE_SYS_POLL_H -# include -# endif -#endif #ifdef WITH_OPENSSL #include #endif -#include "openbsd-compat/sys-tree.h" -#include "openbsd-compat/sys-queue.h" #include "openbsd-compat/openssl-compat.h" #include "atomicio.h" @@ -105,7 +95,9 @@ static Gssctxt *gsscontext = NULL; /* Imports */ extern ServerOptions options; extern u_int utmp_len; +extern struct sshbuf *cfg; extern struct sshbuf *loginmsg; +extern struct include_list includes; extern struct sshauthopt *auth_opts; /* XXX move to permanent ssh->authctxt? */ /* State exported from the child */ @@ -114,6 +106,7 @@ static struct sshbuf *child_state; /* Functions on the monitor that answer unprivileged requests */ int mm_answer_moduli(struct ssh *, int, struct sshbuf *); +int mm_answer_setcompat(struct ssh *, int, struct sshbuf *); int mm_answer_sign(struct ssh *, int, struct sshbuf *); int mm_answer_pwnamallow(struct ssh *, int, struct sshbuf *); int mm_answer_auth2_read_banner(struct ssh *, int, struct sshbuf *); @@ -126,6 +119,7 @@ int mm_answer_keyverify(struct ssh *, int, struct sshbuf *); int mm_answer_pty(struct ssh *, int, struct sshbuf *); int mm_answer_pty_cleanup(struct ssh *, int, struct sshbuf *); int mm_answer_term(struct ssh *, int, struct sshbuf *); +int mm_answer_state(struct ssh *, int, struct sshbuf *); #ifdef USE_PAM int mm_answer_pam_start(struct ssh *, int, struct sshbuf *); @@ -162,7 +156,9 @@ static char *auth_submethod = NULL; static u_int session_id2_len = 0; static u_char *session_id2 = NULL; static pid_t monitor_child_pid; -int auth_attempted = 0; +static int auth_attempted = 0; +static int invalid_user = 0; +static int compat_set = 0; struct mon_table { enum monitor_reqtype type; @@ -184,9 +180,11 @@ static int monitor_read(struct ssh *, struct monitor *, struct mon_table *, static int monitor_read_log(struct monitor *); struct mon_table mon_dispatch_proto20[] = { + {MONITOR_REQ_STATE, MON_ONCE, mm_answer_state}, #ifdef WITH_OPENSSL {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli}, #endif + {MONITOR_REQ_SETCOMPAT, MON_ONCE, mm_answer_setcompat}, {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, @@ -219,6 +217,7 @@ struct mon_table mon_dispatch_proto20[] = { }; struct mon_table mon_dispatch_postauth20[] = { + {MONITOR_REQ_STATE, MON_ONCE, mm_answer_state}, #ifdef WITH_OPENSSL {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, #endif @@ -267,7 +266,7 @@ void monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) { struct mon_table *ent; - int authenticated = 0, partial = 0; + int status, authenticated = 0, partial = 0; debug3("preauth child monitor started"); @@ -284,8 +283,10 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) authctxt->loginmsg = loginmsg; mon_dispatch = mon_dispatch_proto20; - /* Permit requests for moduli and signatures */ + /* Permit requests for state, moduli and signatures */ + monitor_permit(mon_dispatch, MONITOR_REQ_STATE, 1); monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); + monitor_permit(mon_dispatch, MONITOR_REQ_SETCOMPAT, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); /* The first few requests do not require asynchronous access */ @@ -369,11 +370,29 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0) ; + /* Wait for the child's exit status */ + while (waitpid(pmonitor->m_pid, &status, 0) == -1) { + if (errno == EINTR) + continue; + fatal_f("waitpid: %s", strerror(errno)); + } + if (WIFEXITED(status)) { + if (WEXITSTATUS(status) != 0) + fatal_f("preauth child %ld exited with status %d", + (long)pmonitor->m_pid, WEXITSTATUS(status)); + } else if (WIFSIGNALED(status)) { + fatal_f("preauth child %ld terminated by signal %d", + (long)pmonitor->m_pid, WTERMSIG(status)); + } + debug3_f("preauth child %ld terminated successfully", + (long)pmonitor->m_pid); + if (pmonitor->m_recvfd >= 0) close(pmonitor->m_recvfd); if (pmonitor->m_log_sendfd >= 0) close(pmonitor->m_log_sendfd); pmonitor->m_sendfd = pmonitor->m_log_recvfd = -1; + pmonitor->m_pid = -1; } static void @@ -405,6 +424,7 @@ monitor_child_postauth(struct ssh *ssh, struct monitor *pmonitor) mon_dispatch = mon_dispatch_postauth20; /* Permit requests for moduli and signatures */ + monitor_permit(mon_dispatch, MONITOR_REQ_STATE, 1); monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); @@ -462,7 +482,8 @@ monitor_read_log(struct monitor *pmonitor) /* Log it */ if (log_level_name(level) == NULL) fatal_f("invalid log level %u (corrupted message?)", level); - sshlogdirect(level, forced, "%s [preauth]", msg); + sshlogdirect(level, forced, "%s [%s]", msg, + mon_dispatch == mon_dispatch_postauth20 ? "postauth" : "preauth"); sshbuf_free(logmsg); free(msg); @@ -568,6 +589,81 @@ monitor_reset_key_state(void) hostbased_chost = NULL; } +int +mm_answer_state(struct ssh *ssh, int sock, struct sshbuf *unused) +{ + struct sshbuf *m = NULL, *inc = NULL, *hostkeys = NULL; + struct sshbuf *opts = NULL, *confdata = NULL; + struct include_item *item = NULL; + int postauth; + int r; + + debug_f("config len %zu", sshbuf_len(cfg)); + + if ((m = sshbuf_new()) == NULL || + (inc = sshbuf_new()) == NULL || + (opts = sshbuf_new()) == NULL || + (confdata = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + + /* XXX unnecessary? */ + /* pack includes into a string */ + TAILQ_FOREACH(item, &includes, entry) { + if ((r = sshbuf_put_cstring(inc, item->selector)) != 0 || + (r = sshbuf_put_cstring(inc, item->filename)) != 0 || + (r = sshbuf_put_stringb(inc, item->contents)) != 0) + fatal_fr(r, "compose includes"); + } + + hostkeys = pack_hostkeys(); + + /* + * Protocol from monitor to unpriv privsep process: + * string configuration + * uint64 timing_secret XXX move delays to monitor and remove + * string host_keys[] { + * string public_key + * string certificate + * } + * string server_banner + * string client_banner + * string included_files[] { + * string selector + * string filename + * string contents + * } + * string configuration_data (postauth) + * string keystate (postauth) + * string authenticated_user (postauth) + * string session_info (postauth) + * string authopts (postauth) + */ + if ((r = sshbuf_put_stringb(m, cfg)) != 0 || + (r = sshbuf_put_u64(m, options.timing_secret)) != 0 || + (r = sshbuf_put_stringb(m, hostkeys)) != 0 || + (r = sshbuf_put_stringb(m, ssh->kex->server_version)) != 0 || + (r = sshbuf_put_stringb(m, ssh->kex->client_version)) != 0 || + (r = sshbuf_put_stringb(m, inc)) != 0) + fatal_fr(r, "compose config"); + + postauth = (authctxt && authctxt->pw && authctxt->authenticated); + if (postauth) { + /* XXX shouldn't be reachable */ + fatal_f("internal error: called in postauth"); + } + + sshbuf_free(inc); + sshbuf_free(opts); + sshbuf_free(confdata); + sshbuf_free(hostkeys); + + mm_request_send(sock, MONITOR_ANS_STATE, m); + sshbuf_free(m); + debug3_f("done"); + + return (0); +} + #ifdef WITH_OPENSSL int mm_answer_moduli(struct ssh *ssh, int sock, struct sshbuf *m) @@ -593,7 +689,6 @@ mm_answer_moduli(struct ssh *ssh, int sock, struct sshbuf *m) if (dh == NULL) { if ((r = sshbuf_put_u8(m, 0)) != 0) fatal_fr(r, "assemble empty"); - return (0); } else { /* Send first bignum */ DH_get0_pqg(dh, &dh_p, NULL, &dh_g); @@ -609,28 +704,49 @@ mm_answer_moduli(struct ssh *ssh, int sock, struct sshbuf *m) } #endif +int +mm_answer_setcompat(struct ssh *ssh, int sock, struct sshbuf *m) +{ + int r; + + debug3_f("entering"); + + if ((r = sshbuf_get_u32(m, &ssh->compat)) != 0) + fatal_fr(r, "parse"); + compat_set = 1; + + return (0); +} + int mm_answer_sign(struct ssh *ssh, int sock, struct sshbuf *m) { extern int auth_sock; /* XXX move to state struct? */ - struct sshkey *key; + struct sshkey *pubkey, *key; struct sshbuf *sigbuf = NULL; u_char *p = NULL, *signature = NULL; char *alg = NULL; - size_t datlen, siglen, alglen; - int r, is_proof = 0; - u_int keyid, compat; + size_t datlen, siglen; + int r, is_proof = 0, keyid; + u_int compat; const char proof_req[] = "hostkeys-prove-00@openssh.com"; debug3_f("entering"); - if ((r = sshbuf_get_u32(m, &keyid)) != 0 || + /* Make sure the unpriv process sent the compat bits already */ + if (!compat_set) + fatal_f("state error: setcompat never called"); + + if ((r = sshkey_froms(m, &pubkey)) != 0 || (r = sshbuf_get_string(m, &p, &datlen)) != 0 || - (r = sshbuf_get_cstring(m, &alg, &alglen)) != 0 || + (r = sshbuf_get_cstring(m, &alg, NULL)) != 0 || (r = sshbuf_get_u32(m, &compat)) != 0) fatal_fr(r, "parse"); - if (keyid > INT_MAX) - fatal_f("invalid key ID"); + + if ((keyid = get_hostkey_index(pubkey, 1, ssh)) == -1) + fatal_f("unknown hostkey"); + debug_f("hostkey %s index %d", sshkey_ssh_name(pubkey), keyid); + sshkey_free(pubkey); /* * Supported KEX types use SHA1 (20 bytes), SHA256 (32 bytes), @@ -727,7 +843,7 @@ mm_encode_server_options(struct sshbuf *m) (r = sshbuf_put_cstring(m, options.x)) != 0) \ fatal_fr(r, "assemble %s", #x); \ } while (0) -#define M_CP_STRARRAYOPT(x, nx) do { \ +#define M_CP_STRARRAYOPT(x, nx, clobber) do { \ for (i = 0; i < options.nx; i++) { \ if ((r = sshbuf_put_cstring(m, options.x[i])) != 0) \ fatal_fr(r, "assemble %s", #x); \ @@ -748,6 +864,10 @@ mm_answer_pwnamallow(struct ssh *ssh, int sock, struct sshbuf *m) debug3_f("entering"); + /* Make sure the unpriv process sent the compat bits already */ + if (!compat_set) + fatal_f("state error: setcompat never called"); + if (authctxt->attempt++ != 0) fatal_f("multiple attempts for getpwnam"); @@ -761,6 +881,7 @@ mm_answer_pwnamallow(struct ssh *ssh, int sock, struct sshbuf *m) sshbuf_reset(m); if (pwent == NULL) { + invalid_user = 1; if ((r = sshbuf_put_u8(m, 0)) != 0) fatal_fr(r, "assemble fakepw"); authctxt->pw = fakepw(); @@ -924,7 +1045,6 @@ mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m) fatal_fr(r, "assemble PAM"); #endif - debug3("%s: sending result %d", __func__, authenticated); debug3_f("sending result %d", authenticated); mm_request_send(sock, MONITOR_ANS_AUTHPASSWORD, m); @@ -1011,7 +1131,7 @@ int mm_answer_pam_start(struct ssh *ssh, int sock, struct sshbuf *m) { if (!options.use_pam) - fatal("UsePAM not set, but ended up in %s anyway", __func__); + fatal_f("UsePAM not set, but ended up in %s anyway", __func__); start_pam(ssh); @@ -1029,13 +1149,14 @@ mm_answer_pam_account(struct ssh *ssh, int sock, struct sshbuf *m) int r; if (!options.use_pam) - fatal("%s: PAM not enabled", __func__); + fatal_f("PAM not enabled"); ret = do_pam_account(); if ((r = sshbuf_put_u32(m, ret)) != 0 || (r = sshbuf_put_stringb(m, loginmsg)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); + sshbuf_reset(loginmsg); mm_request_send(sock, MONITOR_ANS_PAM_ACCOUNT, m); @@ -1051,11 +1172,11 @@ mm_answer_pam_init_ctx(struct ssh *ssh, int sock, struct sshbuf *m) u_int ok = 0; int r; - debug3("%s", __func__); + debug3_f("entering"); if (!options.kbd_interactive_authentication) - fatal("%s: kbd-int authentication not enabled", __func__); + fatal_f("kbd-int authentication not enabled"); if (sshpam_ctxt != NULL) - fatal("%s: already called", __func__); + fatal_f("already called"); sshpam_ctxt = (sshpam_device.init_ctx)(authctxt); sshpam_authok = NULL; sshbuf_reset(m); @@ -1065,7 +1186,7 @@ mm_answer_pam_init_ctx(struct ssh *ssh, int sock, struct sshbuf *m) ok = 1; } if ((r = sshbuf_put_u32(m, ok)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); mm_request_send(sock, MONITOR_ANS_PAM_INIT_CTX, m); return (0); } @@ -1077,13 +1198,13 @@ mm_answer_pam_query(struct ssh *ssh, int sock, struct sshbuf *m) u_int i, num = 0, *echo_on = 0; int r, ret; - debug3("%s", __func__); + debug3_f("entering"); sshpam_authok = NULL; if (sshpam_ctxt == NULL) - fatal("%s: no context", __func__); + fatal_f("no context"); ret = (sshpam_device.query)(sshpam_ctxt, &name, &info, &num, &prompts, &echo_on); - if (ret == 0 && num == 0) + if (ret == 0 && num == 0 && sshpam_priv_kbdint_authdone(sshpam_ctxt)) sshpam_authok = sshpam_ctxt; if (num > 1 || name == NULL || info == NULL) fatal("sshpam_device.query failed"); @@ -1094,13 +1215,13 @@ mm_answer_pam_query(struct ssh *ssh, int sock, struct sshbuf *m) (r = sshbuf_put_cstring(m, info)) != 0 || (r = sshbuf_put_u32(m, sshpam_get_maxtries_reached())) != 0 || (r = sshbuf_put_u32(m, num)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); free(name); free(info); for (i = 0; i < num; ++i) { if ((r = sshbuf_put_cstring(m, prompts[i])) != 0 || (r = sshbuf_put_u32(m, echo_on[i])) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); free(prompts[i]); } free(prompts); @@ -1118,12 +1239,12 @@ mm_answer_pam_respond(struct ssh *ssh, int sock, struct sshbuf *m) u_int i, num; int r, ret; - debug3("%s", __func__); + debug3_f("entering"); if (sshpam_ctxt == NULL) - fatal("%s: no context", __func__); + fatal_f("no context"); sshpam_authok = NULL; if ((r = sshbuf_get_u32(m, &num)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); if (num > PAM_MAX_NUM_MSG) { fatal_f("Too many PAM messages, got %u, expected <= %u", num, (unsigned)PAM_MAX_NUM_MSG); @@ -1144,7 +1265,7 @@ mm_answer_pam_respond(struct ssh *ssh, int sock, struct sshbuf *m) } sshbuf_reset(m); if ((r = sshbuf_put_u32(m, ret)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); mm_request_send(sock, MONITOR_ANS_PAM_RESPOND, m); auth_method = "keyboard-interactive"; auth_submethod = "pam"; @@ -1158,9 +1279,9 @@ mm_answer_pam_free_ctx(struct ssh *ssh, int sock, struct sshbuf *m) { int r = sshpam_authok != NULL && sshpam_authok == sshpam_ctxt; - debug3("%s", __func__); + debug3_f("entering"); if (sshpam_ctxt == NULL) - fatal("%s: no context", __func__); + fatal_f("no context"); (sshpam_device.free_ctx)(sshpam_ctxt); sshpam_ctxt = sshpam_authok = NULL; sshbuf_reset(m); @@ -1691,10 +1812,10 @@ mm_answer_audit_event(struct ssh *ssh, int socket, struct sshbuf *m) ssh_audit_event_t event; int r; - debug3("%s entering", __func__); + debug3_f("entering"); if ((r = sshbuf_get_u32(m, &n)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); event = (ssh_audit_event_t)n; switch (event) { case SSH_AUTH_FAIL_PUBKEY: @@ -1719,9 +1840,9 @@ mm_answer_audit_command(struct ssh *ssh, int socket, struct sshbuf *m) char *cmd; int r; - debug3("%s entering", __func__); + debug3_f("entering"); if ((r = sshbuf_get_cstring(m, &cmd, NULL)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); /* sanity check command, if so how? */ audit_run_command(cmd); free(cmd); @@ -1797,11 +1918,6 @@ mm_get_keystate(struct ssh *ssh, struct monitor *pmonitor) /* XXX */ -#define FD_CLOSEONEXEC(x) do { \ - if (fcntl(x, F_SETFD, FD_CLOEXEC) == -1) \ - fatal("fcntl(%d, F_SETFD)", x); \ -} while (0) - static void monitor_openfds(struct monitor *mon, int do_logfds) { @@ -1834,8 +1950,6 @@ monitor_openfds(struct monitor *mon, int do_logfds) mon->m_log_recvfd = mon->m_log_sendfd = -1; } -#define MM_MEMSIZE 65536 - struct monitor * monitor_init(void) { @@ -1853,6 +1967,18 @@ monitor_reinit(struct monitor *mon) monitor_openfds(mon, 0); } +int +monitor_auth_attempted(void) +{ + return auth_attempted; +} + +int +monitor_invalid_user(void) +{ + return invalid_user; +} + #ifdef GSSAPI int mm_answer_gss_setup_ctx(struct ssh *ssh, int sock, struct sshbuf *m) diff --git a/monitor.h b/monitor.h index fa48fc6..fe0b00b 100644 --- a/monitor.h +++ b/monitor.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.h,v 1.24 2024/05/17 00:30:24 djm Exp $ */ +/* $OpenBSD: monitor.h,v 1.28 2026/03/02 02:40:15 djm Exp $ */ /* * Copyright 2002 Niels Provos @@ -39,6 +39,7 @@ enum monitor_reqtype { MONITOR_REQ_AUTHPASSWORD = 12, MONITOR_ANS_AUTHPASSWORD = 13, MONITOR_REQ_BSDAUTHQUERY = 14, MONITOR_ANS_BSDAUTHQUERY = 15, MONITOR_REQ_BSDAUTHRESPOND = 16, MONITOR_ANS_BSDAUTHRESPOND = 17, + MONITOR_REQ_SETCOMPAT = 18, MONITOR_REQ_KEYALLOWED = 22, MONITOR_ANS_KEYALLOWED = 23, MONITOR_REQ_KEYVERIFY = 24, MONITOR_ANS_KEYVERIFY = 25, MONITOR_REQ_KEYEXPORT = 26, @@ -54,6 +55,7 @@ enum monitor_reqtype { MONITOR_REQ_GSSUSEROK = 46, MONITOR_ANS_GSSUSEROK = 47, MONITOR_REQ_GSSCHECKMIC = 48, MONITOR_ANS_GSSCHECKMIC = 49, MONITOR_REQ_TERM = 50, + MONITOR_REQ_STATE = 51, MONITOR_ANS_STATE = 52, MONITOR_REQ_PAM_START = 100, MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, @@ -87,6 +89,9 @@ void monitor_child_postauth(struct ssh *, struct monitor *); void monitor_clear_keystate(struct ssh *, struct monitor *); void monitor_apply_keystate(struct ssh *, struct monitor *); +int monitor_auth_attempted(void); +int monitor_invalid_user(void); + /* Prototypes for request sending and receiving */ void mm_request_send(int, enum monitor_reqtype, struct sshbuf *); void mm_request_receive(int, struct sshbuf *); @@ -96,4 +101,6 @@ void mm_get_keystate(struct ssh *, struct monitor *); /* XXX: should be returned via a monitor call rather than config_fd */ void mm_encode_server_options(struct sshbuf *); +struct sshbuf *pack_hostkeys(void); + #endif /* _MONITOR_H_ */ diff --git a/monitor_fdpass.c b/monitor_fdpass.c index a07727a..a2472ab 100644 --- a/monitor_fdpass.c +++ b/monitor_fdpass.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_fdpass.c,v 1.22 2020/10/18 11:32:01 djm Exp $ */ +/* $OpenBSD: monitor_fdpass.c,v 1.23 2026/02/08 19:54:31 dtucker Exp $ */ /* * Copyright 2001 Niels Provos * All rights reserved. @@ -29,22 +29,13 @@ #include #include #include -#ifdef HAVE_SYS_UN_H #include -#endif #include +#include #include #include -#ifdef HAVE_POLL_H -# include -#else -# ifdef HAVE_SYS_POLL_H -# include -# endif -#endif - #include "log.h" #include "monitor_fdpass.h" @@ -103,7 +94,7 @@ mm_send_fd(int sock, int fd) } return 0; #else - error("%s: file descriptor passing not supported", __func__); + error_f("file descriptor passing not supported"); return -1; #endif } diff --git a/monitor_wrap.c b/monitor_wrap.c index 5358c77..81596a4 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.c,v 1.136 2024/06/19 23:24:47 djm Exp $ */ +/* $OpenBSD: monitor_wrap.c,v 1.146 2026/03/02 02:40:15 djm Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -45,7 +46,6 @@ #include #endif -#include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "ssh.h" #ifdef WITH_OPENSSL @@ -106,21 +106,16 @@ mm_log_handler(LogLevel level, int forced, const char *msg, void *ctx) fatal_f("bad length %zu", len); POKE_U32(sshbuf_mutable_ptr(log_msg), len - 4); if (atomicio(vwrite, mon->m_log_sendfd, - sshbuf_mutable_ptr(log_msg), len) != len) + sshbuf_mutable_ptr(log_msg), len) != len) { + if (errno == EPIPE) { + debug_f("write: %s", strerror(errno)); + cleanup_exit(255); + } fatal_f("write: %s", strerror(errno)); + } sshbuf_free(log_msg); } -int -mm_is_monitor(void) -{ - /* - * m_pid is only set in the privileged part, and - * points to the unprivileged child. - */ - return (pmonitor && pmonitor->m_pid > 0); -} - static void mm_reap(void) { @@ -136,17 +131,17 @@ mm_reap(void) } if (WIFEXITED(status)) { if (WEXITSTATUS(status) != 0) { - debug_f("preauth child exited with status %d", + debug_f("child exited with status %d", WEXITSTATUS(status)); cleanup_exit(255); } } else if (WIFSIGNALED(status)) { - error_f("preauth child terminated by signal %d", + error_f("child terminated by signal %d", WTERMSIG(status)); cleanup_exit(signal_is_crash(WTERMSIG(status)) ? EXIT_CHILD_CRASH : 255); } else { - error_f("preauth child terminated abnormally (status=0x%x)", + error_f("child terminated abnormally (status=0x%x)", status); cleanup_exit(EXIT_CHILD_CRASH); } @@ -160,7 +155,7 @@ mm_request_send(int sock, enum monitor_reqtype type, struct sshbuf *m) debug3_f("entering, type %d", type); - if (mlen >= 0xffffffff) + if (mlen >= MONITOR_MAX_MSGLEN) fatal_f("bad length %zu", mlen); POKE_U32(buf, mlen + 1); buf[4] = (u_char) type; /* 1st byte of payload is mesg-type */ @@ -193,7 +188,7 @@ mm_request_receive(int sock, struct sshbuf *m) fatal_f("read: %s", strerror(errno)); } msg_len = PEEK_U32(buf); - if (msg_len > 256 * 1024) + if (msg_len > MONITOR_MAX_MSGLEN) fatal_f("read: bad msg_len %d", msg_len); sshbuf_reset(m); if ((r = sshbuf_reserve(m, msg_len, &p)) != 0) @@ -259,20 +254,33 @@ mm_choose_dh(int min, int nbits, int max) } #endif +void +mm_sshkey_setcompat(struct ssh *ssh) +{ + struct sshbuf *m; + int r; + + debug3_f("entering"); + if ((m = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + if ((r = sshbuf_put_u32(m, ssh->compat)) != 0) + fatal_fr(r, "assemble"); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SETCOMPAT, m); +} + int mm_sshkey_sign(struct ssh *ssh, struct sshkey *key, u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, const char *hostkey_alg, const char *sk_provider, const char *sk_pin, u_int compat) { - struct kex *kex = *pmonitor->m_pkex; struct sshbuf *m; - u_int ndx = kex->host_key_index(key, 0, ssh); int r; debug3_f("entering"); if ((m = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); - if ((r = sshbuf_put_u32(m, ndx)) != 0 || + if ((r = sshkey_puts(key, m)) != 0 || (r = sshbuf_put_string(m, data, datalen)) != 0 || (r = sshbuf_put_cstring(m, hostkey_alg)) != 0 || (r = sshbuf_put_u32(m, compat)) != 0) @@ -285,6 +293,8 @@ mm_sshkey_sign(struct ssh *ssh, struct sshkey *key, u_char **sigp, size_t *lenp, if ((r = sshbuf_get_string(m, sigp, lenp)) != 0) fatal_fr(r, "parse"); sshbuf_free(m); + debug3_f("%s signature len=%zu", hostkey_alg ? hostkey_alg : "(null)", + *lenp); return (0); } @@ -310,7 +320,7 @@ mm_decode_activate_server_options(struct ssh *ssh, struct sshbuf *m) (r = sshbuf_get_cstring(m, &newopts->x, NULL)) != 0) \ fatal_fr(r, "parse %s", #x); \ } while (0) -#define M_CP_STRARRAYOPT(x, nx) do { \ +#define M_CP_STRARRAYOPT(x, nx, clobber) do { \ newopts->x = newopts->nx == 0 ? \ NULL : xcalloc(newopts->nx, sizeof(*newopts->x)); \ for (i = 0; i < newopts->nx; i++) { \ @@ -329,6 +339,17 @@ mm_decode_activate_server_options(struct ssh *ssh, struct sshbuf *m) log_verbose_reset(); for (i = 0; i < options.num_log_verbose; i++) log_verbose_add(options.log_verbose[i]); + + /* use the macro hell to clean up too */ +#define M_CP_STROPT(x) free(newopts->x) +#define M_CP_STRARRAYOPT(x, nx, clobber) do { \ + for (i = 0; i < newopts->nx; i++) \ + free(newopts->x[i]); \ + free(newopts->x); \ + } while (0) + COPY_MATCH_STRING_OPTS(); +#undef M_CP_STROPT +#undef M_CP_STRARRAYOPT free(newopts); } @@ -702,11 +723,11 @@ mm_start_pam(struct ssh *ssh) { struct sshbuf *m; - debug3("%s entering", __func__); + debug3_f("entering"); if (!options.use_pam) - fatal("UsePAM=no, but ended up in %s anyway", __func__); + fatal_f("UsePAM=no, but ended up in %s anyway", __func__); if ((m = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_START, m); sshbuf_free(m); @@ -721,12 +742,12 @@ mm_do_pam_account(void) size_t msglen; int r; - debug3("%s entering", __func__); + debug3_f("entering"); if (!options.use_pam) - fatal("UsePAM=no, but ended up in %s anyway", __func__); + fatal_f("UsePAM=no, but ended up in %s anyway", __func__); if ((m = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_ACCOUNT, m); mm_request_receive_expect(pmonitor->m_recvfd, @@ -734,12 +755,12 @@ mm_do_pam_account(void) if ((r = sshbuf_get_u32(m, &ret)) != 0 || (r = sshbuf_get_cstring(m, &msg, &msglen)) != 0 || (r = sshbuf_put(loginmsg, msg, msglen)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); free(msg); sshbuf_free(m); - debug3("%s returning %d", __func__, ret); + debug3_f("returning %d", ret); return (ret); } @@ -750,17 +771,17 @@ mm_sshpam_init_ctx(Authctxt *authctxt) struct sshbuf *m; int r, success; - debug3("%s", __func__); + debug3_f("entering"); if ((m = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_INIT_CTX, m); - debug3("%s: waiting for MONITOR_ANS_PAM_INIT_CTX", __func__); + debug3_f("waiting for MONITOR_ANS_PAM_INIT_CTX"); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_INIT_CTX, m); if ((r = sshbuf_get_u32(m, &success)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); if (success == 0) { - debug3("%s: pam_init_ctx failed", __func__); + debug3_f("pam_init_ctx failed"); sshbuf_free(m); return (NULL); } @@ -776,19 +797,19 @@ mm_sshpam_query(void *ctx, char **name, char **info, u_int i, n; int r, ret; - debug3("%s", __func__); + debug3_f("entering"); if ((m = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_QUERY, m); - debug3("%s: waiting for MONITOR_ANS_PAM_QUERY", __func__); + debug3_f("waiting for MONITOR_ANS_PAM_QUERY"); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_QUERY, m); if ((r = sshbuf_get_u32(m, &ret)) != 0 || (r = sshbuf_get_cstring(m, name, NULL)) != 0 || (r = sshbuf_get_cstring(m, info, NULL)) != 0 || (r = sshbuf_get_u32(m, &n)) != 0 || (r = sshbuf_get_u32(m, num)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); - debug3("%s: pam_query returned %d", __func__, ret); + fatal_fr(r, "buffer error"); + debug3_f("pam_query returned %d", ret); sshpam_set_maxtries_reached(n); if (*num > PAM_MAX_NUM_MSG) fatal("%s: received %u PAM messages, expected <= %u", @@ -798,7 +819,7 @@ mm_sshpam_query(void *ctx, char **name, char **info, for (i = 0; i < *num; ++i) { if ((r = sshbuf_get_cstring(m, &((*prompts)[i]), NULL)) != 0 || (r = sshbuf_get_u32(m, &((*echo_on)[i]))) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); } sshbuf_free(m); return (ret); @@ -811,23 +832,23 @@ mm_sshpam_respond(void *ctx, u_int num, char **resp) u_int n, i; int r, ret; - debug3("%s", __func__); + debug3_f("entering"); if ((m = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); if ((r = sshbuf_put_u32(m, num)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); for (i = 0; i < num; ++i) { if ((r = sshbuf_put_cstring(m, resp[i])) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); } mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_RESPOND, m); - debug3("%s: waiting for MONITOR_ANS_PAM_RESPOND", __func__); + debug3_f("waiting for MONITOR_ANS_PAM_RESPOND"); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_RESPOND, m); if ((r = sshbuf_get_u32(m, &n)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); ret = (int)n; /* XXX */ - debug3("%s: pam_respond returned %d", __func__, ret); + debug3_f("pam_respond returned %d", ret); sshbuf_free(m); return (ret); } @@ -837,11 +858,11 @@ mm_sshpam_free_ctx(void *ctxtp) { struct sshbuf *m; - debug3("%s", __func__); + debug3_f("entering"); if ((m = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_FREE_CTX, m); - debug3("%s: waiting for MONITOR_ANS_PAM_FREE_CTX", __func__); + debug3_f("waiting for MONITOR_ANS_PAM_FREE_CTX"); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_FREE_CTX, m); sshbuf_free(m); @@ -861,6 +882,72 @@ mm_terminate(void) sshbuf_free(m); } +/* Request state information */ + +void +mm_get_state(struct ssh *ssh, struct include_list *includes, + struct sshbuf *conf, struct sshbuf **confdatap, + uint64_t *timing_secretp, + struct sshbuf **hostkeysp, struct sshbuf **keystatep, + u_char **pw_namep, + struct sshbuf **authinfop, struct sshbuf **auth_optsp) +{ + struct sshbuf *m, *inc; + u_char *cp; + size_t len; + int r; + struct include_item *item; + + debug3_f("entering"); + + if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_STATE, m); + + debug3_f("waiting for MONITOR_ANS_STATE"); + mm_request_receive_expect(pmonitor->m_recvfd, + MONITOR_ANS_STATE, m); + + if ((r = sshbuf_get_string(m, &cp, &len)) != 0 || + (r = sshbuf_get_u64(m, timing_secretp)) != 0 || + (r = sshbuf_froms(m, hostkeysp)) != 0 || + (r = sshbuf_get_stringb(m, ssh->kex->server_version)) != 0 || + (r = sshbuf_get_stringb(m, ssh->kex->client_version)) != 0 || + (r = sshbuf_get_stringb(m, inc)) != 0) + fatal_fr(r, "parse config"); + + /* postauth */ + if (confdatap) { + if ((r = sshbuf_froms(m, confdatap)) != 0 || + (r = sshbuf_froms(m, keystatep)) != 0 || + (r = sshbuf_get_string(m, pw_namep, NULL)) != 0 || + (r = sshbuf_froms(m, authinfop)) != 0 || + (r = sshbuf_froms(m, auth_optsp)) != 0) + fatal_fr(r, "parse config postauth"); + } + + if (conf != NULL && (r = sshbuf_put(conf, cp, len))) + fatal_fr(r, "sshbuf_put"); + + while (sshbuf_len(inc) != 0) { + item = xcalloc(1, sizeof(*item)); + if ((item->contents = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + if ((r = sshbuf_get_cstring(inc, &item->selector, NULL)) != 0 || + (r = sshbuf_get_cstring(inc, &item->filename, NULL)) != 0 || + (r = sshbuf_get_stringb(inc, item->contents)) != 0) + fatal_fr(r, "parse includes"); + TAILQ_INSERT_TAIL(includes, item, entry); + } + + free(cp); + sshbuf_free(m); + sshbuf_free(inc); + + debug3_f("done"); +} + static void mm_chall_setup(char **name, char **infotxt, u_int *numprompts, char ***prompts, u_int **echo_on) @@ -944,12 +1031,12 @@ mm_audit_event(struct ssh *ssh, ssh_audit_event_t event) struct sshbuf *m; int r; - debug3("%s entering", __func__); + debug3_f("entering"); if ((m = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); if ((r = sshbuf_put_u32(m, event)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_EVENT, m); sshbuf_free(m); @@ -961,12 +1048,12 @@ mm_audit_run_command(const char *command) struct sshbuf *m; int r; - debug3("%s entering command %s", __func__, command); + debug3_f("entering command %s", command); if ((m = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); if ((r = sshbuf_put_cstring(m, command)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, m); sshbuf_free(m); diff --git a/monitor_wrap.h b/monitor_wrap.h index e768036..c2f7f97 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.h,v 1.51 2024/05/17 06:42:04 jsg Exp $ */ +/* $OpenBSD: monitor_wrap.h,v 1.54 2026/03/02 02:40:15 djm Exp $ */ /* * Copyright 2002 Niels Provos @@ -28,6 +28,10 @@ #ifndef _MM_WRAP_H_ #define _MM_WRAP_H_ +#define MONITOR_MAX_MSGLEN (4 * 1024 * 1024) +/* The configuration has to fit in a monitor message along with other state */ +#define MONITOR_MAX_CFGLEN (MONITOR_MAX_MSGLEN - (64 * 1024)) + enum mm_keytype { MM_NOKEY, MM_HOSTKEY, MM_USERKEY }; struct ssh; @@ -42,6 +46,7 @@ int mm_is_monitor(void); #ifdef WITH_OPENSSL DH *mm_choose_dh(int, int, int); #endif +void mm_sshkey_setcompat(struct ssh *); int mm_sshkey_sign(struct ssh *, struct sshkey *, u_char **, size_t *, const u_char *, size_t, const char *, const char *, const char *, u_int compat); @@ -90,6 +95,12 @@ void mm_session_pty_cleanup2(struct Session *); void mm_send_keystate(struct ssh *, struct monitor*); +/* state */ +struct include_list; +void mm_get_state(struct ssh *, struct include_list *, struct sshbuf *, + struct sshbuf **, uint64_t *, struct sshbuf **, struct sshbuf **, + u_char **, struct sshbuf **, struct sshbuf **); + /* bsdauth */ int mm_bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **); int mm_bsdauth_respond(void *, u_int, char **); diff --git a/msg.c b/msg.c index a03caeb..8173598 100644 --- a/msg.c +++ b/msg.c @@ -1,4 +1,4 @@ -/* $OpenBSD: msg.c,v 1.21 2024/05/17 00:30:24 djm Exp $ */ +/* $OpenBSD: msg.c,v 1.22 2026/02/14 00:18:34 jsg Exp $ */ /* * Copyright (c) 2002 Markus Friedl. All rights reserved. * @@ -26,16 +26,13 @@ #include "includes.h" #include -#include #include -#include #include #include #include #include "sshbuf.h" -#include "ssherr.h" #include "log.h" #include "atomicio.h" #include "msg.h" diff --git a/mux.c b/mux.c index 0529299..0cd1697 100644 --- a/mux.c +++ b/mux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mux.c,v 1.102 2024/07/25 22:40:08 djm Exp $ */ +/* $OpenBSD: mux.c,v 1.113 2026/04/02 07:39:57 djm Exp $ */ /* * Copyright (c) 2002-2008 Damien Miller * @@ -20,12 +20,13 @@ #include "includes.h" #include +#include #include #include #include #include -#include +#include #include #include #include @@ -34,41 +35,20 @@ #include #include #include -#ifdef HAVE_PATHS_H -#include -#endif - -#ifdef HAVE_POLL_H -#include -#else -# ifdef HAVE_SYS_POLL_H -# include -# endif -#endif -#ifdef HAVE_UTIL_H -# include -#endif - -#include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "log.h" #include "ssh.h" #include "ssh2.h" -#include "pathnames.h" #include "misc.h" #include "match.h" #include "sshbuf.h" #include "channels.h" -#include "msg.h" #include "packet.h" #include "monitor_fdpass.h" #include "sshpty.h" -#include "sshkey.h" #include "readconf.h" #include "clientloop.h" -#include "ssherr.h" -#include "misc.h" /* from ssh.c */ extern int tty_flag; @@ -133,6 +113,7 @@ struct mux_master_state { #define MUX_C_NEW_STDIO_FWD 0x10000008 #define MUX_C_STOP_LISTENING 0x10000009 #define MUX_C_PROXY 0x1000000f +#define MUX_C_EXT_INFO 0x20000001 #define MUX_S_OK 0x80000001 #define MUX_S_PERMISSION_DENIED 0x80000002 #define MUX_S_FAILURE 0x80000003 @@ -142,12 +123,18 @@ struct mux_master_state { #define MUX_S_REMOTE_PORT 0x80000007 #define MUX_S_TTY_ALLOC_FAIL 0x80000008 #define MUX_S_PROXY 0x8000000f +#define MUX_S_EXT_INFO 0x90000001 /* type codes for MUX_C_OPEN_FWD and MUX_C_CLOSE_FWD */ #define MUX_FWD_LOCAL 1 #define MUX_FWD_REMOTE 2 #define MUX_FWD_DYNAMIC 3 +#define MUX_EXT_INFO 0x00000001 + +/* Bitmask of supported extensions */ +static u_int extensions = 0; + static void mux_session_confirm(struct ssh *, int, int, void *); static void mux_stdio_confirm(struct ssh *, int, int, void *); @@ -169,6 +156,8 @@ static int mux_master_process_stop_listening(struct ssh *, u_int, Channel *, struct sshbuf *, struct sshbuf *); static int mux_master_process_proxy(struct ssh *, u_int, Channel *, struct sshbuf *, struct sshbuf *); +static int mux_master_process_ext_info(struct ssh *, u_int, + Channel *, struct sshbuf *, struct sshbuf *); static const struct { u_int type; @@ -184,6 +173,7 @@ static const struct { { MUX_C_NEW_STDIO_FWD, mux_master_process_stdio_fwd }, { MUX_C_STOP_LISTENING, mux_master_process_stop_listening }, { MUX_C_PROXY, mux_master_process_proxy }, + { MUX_C_EXT_INFO, mux_master_process_ext_info }, { 0, NULL } }; @@ -298,8 +288,13 @@ mux_master_process_hello(struct ssh *ssh, u_int rid, error_fr(r, "parse extension"); return -1; } - debug2_f("Unrecognised extension \"%s\" length %zu", - name, value_len); + if (strcmp(name, "info") == 0) { + debug_f("Received 'info' extension"); + extensions |= MUX_EXT_INFO; + } else { + debug2_f("Unrecognised extension \"%s\" length %zu", + name, value_len); + } free(name); } state->hello_rcvd = 1; @@ -461,6 +456,8 @@ mux_master_process_new_session(struct ssh *ssh, u_int rid, nc = channel_new(ssh, "session", SSH_CHANNEL_OPENING, new_fd[0], new_fd[1], new_fd[2], window, packetmax, CHAN_EXTENDED_WRITE, "client-session", CHANNEL_NONBLOCK_STDIO); + if (cctx->want_tty) + channel_set_tty(ssh, nc); nc->ctl_chan = c->self; /* link session -> control channel */ c->ctl_child_id = nc->self; /* link control -> session channel */ @@ -503,6 +500,43 @@ mux_master_process_alive_check(struct ssh *ssh, u_int rid, return 0; } +/* The "info" extension. */ +static int +mux_master_process_ext_info(struct ssh *ssh, u_int rid, + Channel *c, struct sshbuf *m, struct sshbuf *reply) +{ + int r; + u_int status = 0; + char *name = NULL, *msg = NULL; + + debug2_f("channel %d: info request", c->self); + + if ((r = sshbuf_get_cstring(m, &name, NULL)) != 0) + fatal_fr(r, "parse"); + + if (strcmp(name, "connection") == 0) { + if ((msg = connection_info_message(ssh)) == NULL) + fatal_f("connection_info_message"); + status = 1; + } else if (strcmp(name, "channels") == 0) { + if ((msg = channel_open_message(ssh)) == NULL) + fatal_f("channel_open_message"); + status = 1; + } else { + msg = xstrdup("info request type not supported"); + } + + /* prepare reply */ + if ((r = sshbuf_put_u32(reply, MUX_S_EXT_INFO)) != 0 || + (r = sshbuf_put_u32(reply, rid)) != 0 || + (r = sshbuf_put_u32(reply, status)) != 0 || + (r = sshbuf_put_cstring(reply, msg)) != 0) + fatal_fr(r, "reply"); + free(msg); + + return 0; +} + static int mux_master_process_terminate(struct ssh *ssh, u_int rid, Channel *c, struct sshbuf *m, struct sshbuf *reply) @@ -592,7 +626,7 @@ compare_forward(struct Forward *a, struct Forward *b) } static void -mux_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt) +mux_confirm_remote_forward(struct ssh *ssh, int type, uint32_t seq, void *ctxt) { struct mux_channel_confirm_ctx *fctx = ctxt; char *failmsg = NULL; @@ -677,6 +711,7 @@ mux_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt) if (c->mux_pause <= 0) fatal_f("mux_pause %d", c->mux_pause); c->mux_pause = 0; /* start processing messages again */ + free(fctx); } static int @@ -932,7 +967,7 @@ mux_master_process_close_fwd(struct ssh *ssh, u_int rid, } else { /* local and dynamic forwards */ /* Ditto */ if (channel_cancel_lport_listener(ssh, &fwd, fwd.connect_port, - &options.fwd_opts) == -1) + &options.fwd_opts) != 1) error_reason = "port not found"; } @@ -1137,6 +1172,16 @@ mux_master_process_proxy(struct ssh *ssh, u_int rid, debug_f("channel %d: proxy request", c->self); + if (options.control_master == SSHCTL_MASTER_ASK || + options.control_master == SSHCTL_MASTER_AUTO_ASK) { + if (!ask_permission("Allow multiplex proxy connection?")) { + debug2_f("proxy refused by user"); + reply_error(reply, MUX_S_PERMISSION_DENIED, rid, + "Permission denied"); + return 0; + } + } + c->mux_rcb = channel_proxy_downstream; if ((r = sshbuf_put_u32(reply, MUX_S_PROXY)) != 0 || (r = sshbuf_put_u32(reply, rid)) != 0) @@ -1168,7 +1213,10 @@ mux_master_read_cb(struct ssh *ssh, Channel *c) if ((r = sshbuf_put_u32(out, MUX_MSG_HELLO)) != 0 || (r = sshbuf_put_u32(out, SSHMUX_VER)) != 0) fatal_fr(r, "reply"); - /* no extensions */ + /* "info" extension */ + if ((r = sshbuf_put_cstring(out, "info")) != 0 || + (r = sshbuf_put_cstring(out, "0")) != 0) + fatal_fr(r, "put info extension"); if ((r = sshbuf_put_stringb(c->output, out)) != 0) fatal_fr(r, "enqueue"); debug3_f("channel %d: hello sent", c->self); @@ -1397,12 +1445,8 @@ mux_session_confirm(struct ssh *ssh, int id, int success, void *arg) } } - if (cctx->want_agent_fwd && options.forward_agent) { - debug("Requesting authentication agent forwarding."); - channel_request_start(ssh, id, "auth-agent-req@openssh.com", 0); - if ((r = sshpkt_send(ssh)) != 0) - fatal_fr(r, "send"); - } + if (cctx->want_agent_fwd && options.forward_agent) + client_channel_reqest_agent_forwarding(ssh, id); client_session2_setup(ssh, id, cctx->want_tty, cctx->want_subsys, cctx->term, &cctx->tio, c->rfd, cctx->cmd, cctx->env); @@ -1643,7 +1687,13 @@ mux_client_hello_exchange(int fd, int timeout_ms) error_fr(r, "parse extension"); goto out; } - debug2("Unrecognised master extension \"%s\"", name); + /* Process extensions. */ + if (strcmp(name, "info") == 0) { + debug("Received 'info' extension"); + extensions |= MUX_EXT_INFO; + } else { + debug2("Unrecognised master extension \"%s\"", name); + } free(name); } /* success */ @@ -1704,6 +1754,57 @@ mux_client_request_alive(int fd) return pid; } +static char * +mux_client_request_info(int fd, const char *name) +{ + struct sshbuf *m; + char *e, *msg; + u_int type, rid, status; + int r; + + debug3_f("entering"); + + if ((m = sshbuf_new()) == NULL) + fatal_f("sshbuf_new"); + if ((r = sshbuf_put_u32(m, MUX_C_EXT_INFO)) != 0 || + (r = sshbuf_put_u32(m, muxclient_request_id)) != 0 || + (r = sshbuf_put_cstring(m, name)) != 0) + fatal_fr(r, "assemble"); + + if (mux_client_write_packet(fd, m) != 0) + fatal_f("write packet: %s", strerror(errno)); + + sshbuf_reset(m); + + /* Read their reply */ + if (mux_client_read_packet(fd, m) != 0) { + sshbuf_free(m); + return 0; + } + + if ((r = sshbuf_get_u32(m, &type)) != 0) + fatal_fr(r, "parse type"); + if (type != MUX_S_EXT_INFO) { + if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0) + fatal_fr(r, "parse error message"); + fatal_f("master returned error: %s", e); + } + + if ((r = sshbuf_get_u32(m, &rid)) != 0) + fatal_fr(r, "parse remote ID"); + if (rid != muxclient_request_id) + fatal_f("out of sequence reply: my id %u theirs %u", + muxclient_request_id, rid); + if ((r = sshbuf_get_u32(m, &status)) != 0 || + (r = sshbuf_get_cstring(m, &msg, NULL)) != 0) + fatal_fr(r, "parse connection info"); + sshbuf_free(m); + + muxclient_request_id++; + + return msg; +} + static void mux_client_request_terminate(int fd) { @@ -2203,8 +2304,10 @@ mux_client_request_stdio_fwd(int fd) sshbuf_reset(m); if (mux_client_read_packet(fd, m) != 0) { if (errno == EPIPE || - (errno == EINTR && muxclient_terminate != 0)) + (errno == EINTR && muxclient_terminate != 0)) { + sshbuf_free(m); return 0; + } fatal_f("mux_client_read_packet: %s", strerror(errno)); } fatal_f("master returned unexpected message %u", type); @@ -2267,6 +2370,7 @@ muxclient(const char *path) struct sockaddr_un addr; int sock, timeout = options.connection_timeout, timeout_ms = -1; u_int pid; + char *info = NULL; if (muxclient_command == 0) { if (options.stdio_forward_host != NULL) @@ -2337,6 +2441,17 @@ muxclient(const char *path) fatal_f("master alive check failed"); fprintf(stderr, "Master running (pid=%u)\r\n", pid); exit(0); + case SSHMUX_COMMAND_CONNINFO: + case SSHMUX_COMMAND_CHANINFO: + if (!(extensions & MUX_EXT_INFO)) + fatal("mux server does not support info request"); + info = mux_client_request_info(sock, + muxclient_command == SSHMUX_COMMAND_CONNINFO ? + "connection" : "channels"); + if (info == NULL) + fatal_f("info request failed"); + printf("%s", info); + exit(0); case SSHMUX_COMMAND_TERMINATE: mux_client_request_terminate(sock); if (options.log_level != SYSLOG_LEVEL_QUIET) diff --git a/myproposal.h b/myproposal.h index 3bdc2e9..d992d8b 100644 --- a/myproposal.h +++ b/myproposal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: myproposal.h,v 1.73 2024/09/09 02:39:57 djm Exp $ */ +/* $OpenBSD: myproposal.h,v 1.78 2026/02/05 22:05:49 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -25,21 +25,21 @@ */ #define KEX_SERVER_KEX \ + "mlkem768x25519-sha256," \ "sntrup761x25519-sha512," \ "sntrup761x25519-sha512@openssh.com," \ - "mlkem768x25519-sha256," \ "curve25519-sha256," \ "curve25519-sha256@libssh.org," \ "ecdh-sha2-nistp256," \ "ecdh-sha2-nistp384," \ - "ecdh-sha2-nistp521," \ + "ecdh-sha2-nistp521" \ + +#define KEX_CLIENT_KEX KEX_SERVER_KEX "," \ "diffie-hellman-group-exchange-sha256," \ "diffie-hellman-group16-sha512," \ "diffie-hellman-group18-sha512," \ "diffie-hellman-group14-sha256" -#define KEX_CLIENT_KEX KEX_SERVER_KEX - #define KEX_DEFAULT_PK_ALG \ "ssh-ed25519-cert-v01@openssh.com," \ "ecdsa-sha2-nistp256-cert-v01@openssh.com," \ @@ -47,6 +47,7 @@ "ecdsa-sha2-nistp521-cert-v01@openssh.com," \ "sk-ssh-ed25519-cert-v01@openssh.com," \ "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com," \ + "webauthn-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com," \ "rsa-sha2-512-cert-v01@openssh.com," \ "rsa-sha2-256-cert-v01@openssh.com," \ "ssh-ed25519," \ @@ -55,13 +56,14 @@ "ecdsa-sha2-nistp521," \ "sk-ssh-ed25519@openssh.com," \ "sk-ecdsa-sha2-nistp256@openssh.com," \ + "webauthn-sk-ecdsa-sha2-nistp256@openssh.com," \ "rsa-sha2-512," \ "rsa-sha2-256" #define KEX_SERVER_ENCRYPT \ "chacha20-poly1305@openssh.com," \ - "aes128-ctr,aes192-ctr,aes256-ctr," \ - "aes128-gcm@openssh.com,aes256-gcm@openssh.com" + "aes128-gcm@openssh.com,aes256-gcm@openssh.com," \ + "aes128-ctr,aes192-ctr,aes256-ctr" #define KEX_CLIENT_ENCRYPT KEX_SERVER_ENCRYPT @@ -87,6 +89,7 @@ "ecdsa-sha2-nistp521," \ "sk-ssh-ed25519@openssh.com," \ "sk-ecdsa-sha2-nistp256@openssh.com," \ + "webauthn-sk-ecdsa-sha2-nistp256@openssh.com," \ "rsa-sha2-512," \ "rsa-sha2-256" diff --git a/nchan.c b/nchan.c index bd4758a..c9d8e79 100644 --- a/nchan.c +++ b/nchan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nchan.c,v 1.76 2024/07/25 22:40:08 djm Exp $ */ +/* $OpenBSD: nchan.c,v 1.77 2026/02/14 00:18:34 jsg Exp $ */ /* * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. * @@ -32,10 +32,8 @@ #include #include -#include "openbsd-compat/sys-queue.h" #include "ssh2.h" #include "sshbuf.h" -#include "ssherr.h" #include "packet.h" #include "channels.h" #include "compat.h" diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in index 1d54995..53c87db 100644 --- a/openbsd-compat/Makefile.in +++ b/openbsd-compat/Makefile.in @@ -3,12 +3,14 @@ piddir=@piddir@ srcdir=@srcdir@ top_srcdir=@top_srcdir@ +BUILDDIR=@abs_top_builddir@ VPATH=@srcdir@ CC=@CC@ LD=@LD@ CFLAGS=@CFLAGS@ CFLAGS_NOPIE=@CFLAGS_NOPIE@ -CPPFLAGS=-I. -I.. -I$(srcdir) -I$(srcdir)/.. @CPPFLAGS@ @DEFS@ +COMPATINCLUDES="$(BUILDDIR)/@COMPATINCLUDES@" +CPPFLAGS=-I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(COMPATINCLUDES) @CPPFLAGS@ @DEFS@ PICFLAG=@PICFLAG@ LIBS=@LIBS@ AR=@AR@ @@ -120,3 +122,4 @@ clean: distclean: clean rm -f Makefile *~ + rm -rf include diff --git a/openbsd-compat/arc4random.c b/openbsd-compat/arc4random.c index ffd3373..376a893 100644 --- a/openbsd-compat/arc4random.c +++ b/openbsd-compat/arc4random.c @@ -32,9 +32,7 @@ #include #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include #include diff --git a/openbsd-compat/arc4random.h b/openbsd-compat/arc4random.h index af2d5c1..8f68428 100644 --- a/openbsd-compat/arc4random.h +++ b/openbsd-compat/arc4random.h @@ -65,7 +65,7 @@ _rs_forkdetect(void) static inline int _rs_allocate(struct _rs **rsp, struct _rsx **rsxp) { -#if defined(MAP_ANON) && defined(MAP_PRIVATE) +#if defined(HAVE_MMAP) && defined(MAP_ANON) && defined(MAP_PRIVATE) if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) return (-1); @@ -84,7 +84,7 @@ _rs_allocate(struct _rs **rsp, struct _rsx **rsxp) *rsp = NULL; return (-1); } -#endif +#endif /* HAVE_MMAP et al */ _ARC4_ATFORK(_rs_forkhandler); return (0); diff --git a/openbsd-compat/arc4random_uniform.c b/openbsd-compat/arc4random_uniform.c index 591f92d..59d5168 100644 --- a/openbsd-compat/arc4random_uniform.c +++ b/openbsd-compat/arc4random_uniform.c @@ -20,9 +20,7 @@ #include "includes.h" -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #ifndef HAVE_ARC4RANDOM_UNIFORM diff --git a/openbsd-compat/bcrypt_pbkdf.c b/openbsd-compat/bcrypt_pbkdf.c index 5a22ba3..33c9ce1 100644 --- a/openbsd-compat/bcrypt_pbkdf.c +++ b/openbsd-compat/bcrypt_pbkdf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bcrypt_pbkdf.c,v 1.16 2020/08/02 18:35:48 tb Exp $ */ +/* $OpenBSD: bcrypt_pbkdf.c,v 1.17 2022/12/27 17:10:08 jmc Exp $ */ /* * Copyright (c) 2013 Ted Unangst * @@ -49,7 +49,7 @@ * function with the following modifications: * 1. The input password and salt are preprocessed with SHA512. * 2. The output length is expanded to 256 bits. - * 3. Subsequently the magic string to be encrypted is lengthened and modifed + * 3. Subsequently the magic string to be encrypted is lengthened and modified * to "OxychromaticBlowfishSwatDynamite" * 4. The hash function is defined to perform 64 rounds of initial state * expansion. (More rounds are performed by iterating the hash.) @@ -73,7 +73,7 @@ static void bcrypt_hash(uint8_t *sha2pass, uint8_t *sha2salt, uint8_t *out) { blf_ctx state; - uint8_t ciphertext[BCRYPT_HASHSIZE] = + uint8_t __attribute__ ((__nonstring__)) ciphertext[BCRYPT_HASHSIZE] = "OxychromaticBlowfishSwatDynamite"; uint32_t cdata[BCRYPT_WORDS]; int i; diff --git a/openbsd-compat/bsd-misc.c b/openbsd-compat/bsd-misc.c index 226a591..d5cc375 100644 --- a/openbsd-compat/bsd-misc.c +++ b/openbsd-compat/bsd-misc.c @@ -18,12 +18,11 @@ #include "includes.h" #include +#include #ifdef HAVE_SYS_SELECT_H # include #endif -#ifdef HAVE_SYS_TIME_H -# include -#endif +#include #include #include @@ -158,6 +157,15 @@ utimensat(int fd, const char *path, const struct timespec times[2], } #endif +#ifndef HAVE_DIRFD +int +dirfd(void *dir) +{ + errno = ENOSYS; + return -1; +} +#endif + #ifndef HAVE_FCHOWNAT /* * A limited implementation of fchownat() that only implements the @@ -220,6 +228,46 @@ fchmodat(int fd, const char *path, mode_t mode, int flag) } #endif +#ifndef HAVE_FSTATAT +/* + * A limited implementation of fstatat that just has what OpenSSH uses: + * cwd-relative and absolute paths, with or without following symlinks. + */ +int +fstatat(int dirfd, const char *path, struct stat *sb, int flag) +{ + if (dirfd != AT_FDCWD && path && path[0] != '/') { + errno = ENOSYS; + return -1; + } + if (flag == 0) + return stat(path, sb); + else if (flag == AT_SYMLINK_NOFOLLOW) + return lstat(path, sb); + errno = ENOSYS; + return -1; +} +#endif + +#ifndef HAVE_UNLINKAT +/* + * A limited implementation of unlinkat that just has what OpenSSH uses: + * cwd-relative and absolute paths. + */ +int +unlinkat(int dirfd, const char *path, int flag) +{ + if (dirfd != AT_FDCWD && path && path[0] != '/') { + errno = ENOSYS; + return -1; + } + if (flag == 0) + return unlink(path); + errno = ENOSYS; + return -1; +} +#endif + #ifndef HAVE_TRUNCATE int truncate(const char *path, off_t length) { @@ -356,7 +404,15 @@ getpgid(pid_t pid) #ifndef HAVE_PLEDGE int -pledge(const char *promises, const char *paths[]) +pledge(const char *promises, const char *execpromises) +{ + return 0; +} +#endif + +#ifndef HAVE_UNVEIL +int +unveil(const char *path, const char *permissions) { return 0; } @@ -447,6 +503,30 @@ localtime_r(const time_t *timep, struct tm *result) } #endif +#ifndef HAVE_CLOCK_GETTIME +int +clock_gettime(clockid_t clockid, struct timespec *ts) +{ + struct timeval tv; + + if (clockid != CLOCK_REALTIME) { + errno = ENOSYS; + return -1; + } + if (ts == NULL) { + errno = EFAULT; + return -1; + } + + if (gettimeofday(&tv, NULL) == -1) + return -1; + + ts->tv_sec = tv.tv_sec; + ts->tv_nsec = (long)tv.tv_usec * 1000; + return 0; +} +#endif + #ifdef ASAN_OPTIONS const char *__asan_default_options(void) { return ASAN_OPTIONS; diff --git a/openbsd-compat/bsd-misc.h b/openbsd-compat/bsd-misc.h index 61ead1b..53e569d 100644 --- a/openbsd-compat/bsd-misc.h +++ b/openbsd-compat/bsd-misc.h @@ -65,6 +65,10 @@ struct timeval { int utimes(const char *, struct timeval *); #endif /* HAVE_UTIMES */ +#ifndef HAVE_DIRFD +int dirfd(void *); +#endif + #ifndef AT_FDCWD # define AT_FDCWD (-2) #endif @@ -77,6 +81,14 @@ int fchmodat(int, const char *, mode_t, int); int fchownat(int, const char *, uid_t, gid_t, int); #endif +#ifdef HAVE_FSTATAT +int fstatat(int, const char *, struct stat *, int); +#endif + +#ifdef HAVE_UNLINKAT +int unlinkat(int, const char *, int); +#endif + #ifndef HAVE_TRUNCATE int truncate (const char *, off_t); #endif /* HAVE_TRUNCATE */ @@ -144,7 +156,11 @@ int pselect(int, fd_set *, fd_set *, fd_set *, const struct timespec *, #endif #ifndef HAVE_PLEDGE -int pledge(const char *promises, const char *paths[]); +int pledge(const char *promises, const char *execpromises); +#endif + +#ifndef HAVE_UNVEIL +int unveil(const char *, const char *); #endif /* bsd-err.h */ @@ -190,6 +206,14 @@ int flock(int, int); struct tm *localtime_r(const time_t *, struct tm *); #endif +#ifndef HAVE_CLOCK_GETTIME +typedef int clockid_t; +#ifndef CLOCK_REALTIME +# define CLOCK_REALTIME 0 +#endif +int clock_gettime(clockid_t, struct timespec *); +#endif + #ifndef HAVE_REALPATH #define realpath(x, y) (sftp_realpath((x), (y))) #endif diff --git a/openbsd-compat/bsd-openpty.c b/openbsd-compat/bsd-openpty.c index f550700..2f12862 100644 --- a/openbsd-compat/bsd-openpty.c +++ b/openbsd-compat/bsd-openpty.c @@ -38,10 +38,9 @@ #include #include +#include -#ifdef HAVE_SYS_STAT_H -# include -#endif +#include #ifdef HAVE_SYS_IOCTL_H # include #endif @@ -50,9 +49,7 @@ # include #endif -#ifdef HAVE_UTIL_H -# include -#endif /* HAVE_UTIL_H */ +#include #ifdef HAVE_PTY_H # include diff --git a/openbsd-compat/bsd-poll.h b/openbsd-compat/bsd-poll.h index ae865a6..bebd5d8 100644 --- a/openbsd-compat/bsd-poll.h +++ b/openbsd-compat/bsd-poll.h @@ -31,11 +31,7 @@ #define _COMPAT_POLL_H_ #include -#ifdef HAVE_POLL_H -# include -#elif HAVE_SYS_POLL_H -# include -#endif +#include #ifndef HAVE_STRUCT_POLLFD_FD typedef struct pollfd { @@ -76,7 +72,11 @@ typedef struct pollfd { #endif /* !HAVE_STRUCT_POLLFD_FD */ #ifndef HAVE_NFDS_T +# ifdef POLL_NFDS_T_ULONG +typedef unsigned long nfds_t; +# else typedef unsigned int nfds_t; +# endif #endif #ifndef HAVE_POLL diff --git a/openbsd-compat/bsd-pselect.c b/openbsd-compat/bsd-pselect.c index b363208..26bdc3e 100644 --- a/openbsd-compat/bsd-pselect.c +++ b/openbsd-compat/bsd-pselect.c @@ -40,75 +40,47 @@ #include #include "log.h" -#include "misc.h" /* for set_nonblock */ #ifndef HAVE_SIGHANDLER_T typedef void (*sighandler_t)(int); #endif static sighandler_t saved_sighandler[_NSIG]; +static int notify_pipe[2]; /* 0 = read end, 1 = write end */ /* - * Set up the descriptors. Because they are close-on-exec, in the case - * where sshd's re-exec fails notify_pipe will still point to a descriptor - * that was closed by the exec attempt but if that descriptor has been - * reopened then we'll attempt to use that. Ensure that notify_pipe is - * outside of the range used by sshd re-exec but within NFDBITS (so we don't - * need to expand the fd_sets). + * Because the debugging for this is so noisy, we only output on the first + * call, and suppress it thereafter. */ -#define REEXEC_MIN_FREE_FD (STDERR_FILENO + 4) -static int -pselect_notify_setup_fd(int *fd) +static int suppress_debug; + +static void +pselect_set_nonblock(int fd) { - int r; + int val; - if ((r = fcntl(*fd, F_DUPFD, REEXEC_MIN_FREE_FD)) < 0 || - fcntl(r, F_SETFD, FD_CLOEXEC) < 0 || r >= FD_SETSIZE) - return -1; - (void)close(*fd); - return (*fd = r); + if ((val = fcntl(fd, F_GETFL)) == -1 || + fcntl(fd, F_SETFL, val|O_NONBLOCK) == -1) + error_f("fcntl: %s", strerror(errno)); } /* * we write to this pipe if a SIGCHLD is caught in order to avoid - * the race between select() and child_terminated + * the race between select() and child_terminated. */ -static pid_t notify_pid; -static int notify_pipe[2]; -static void +static int pselect_notify_setup(void) { - static int initialized; - - if (initialized && notify_pid == getpid()) - return; - if (notify_pid == 0) - debug3_f("initializing"); - else { - debug3_f("pid changed, reinitializing"); - if (notify_pipe[0] != -1) - close(notify_pipe[0]); - if (notify_pipe[1] != -1) - close(notify_pipe[1]); - } if (pipe(notify_pipe) == -1) { error("pipe(notify_pipe) failed %s", strerror(errno)); - } else if (pselect_notify_setup_fd(¬ify_pipe[0]) == -1 || - pselect_notify_setup_fd(¬ify_pipe[1]) == -1) { - error("fcntl(notify_pipe, ...) failed %s", strerror(errno)); - close(notify_pipe[0]); - close(notify_pipe[1]); - } else { - set_nonblock(notify_pipe[0]); - set_nonblock(notify_pipe[1]); - notify_pid = getpid(); - debug3_f("pid %d saved %d pipe0 %d pipe1 %d", getpid(), - notify_pid, notify_pipe[0], notify_pipe[1]); - initialized = 1; - return; + notify_pipe[0] = notify_pipe[1] = -1; + return -1; } - notify_pipe[0] = -1; /* read end */ - notify_pipe[1] = -1; /* write end */ + pselect_set_nonblock(notify_pipe[0]); + pselect_set_nonblock(notify_pipe[1]); + if (!suppress_debug) + debug3_f("pipe0 %d pipe1 %d", notify_pipe[0], notify_pipe[1]); + return 0; } static void pselect_notify_parent(void) @@ -132,6 +104,8 @@ pselect_notify_done(fd_set *readset) debug2_f("reading"); FD_CLR(notify_pipe[0], readset); } + (void)close(notify_pipe[0]); + (void)close(notify_pipe[1]); } /*ARGSUSED*/ @@ -167,26 +141,29 @@ pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, if (mask == NULL) /* no signal mask, just call select */ return select(nfds, readfds, writefds, exceptfds, tvp); - /* For each signal we're unmasking, install our handler if needed. */ + /* For each signal unmasked, save old handler and install ours. */ for (sig = 0; sig < _NSIG; sig++) { + saved_sighandler[sig] = NULL; if (sig == SIGKILL || sig == SIGSTOP || sigismember(mask, sig)) continue; if (sigaction(sig, NULL, &sa) == 0 && sa.sa_handler != SIG_IGN && sa.sa_handler != SIG_DFL) { unmasked = 1; - if (sa.sa_handler == pselect_sig_handler) - continue; sa.sa_handler = pselect_sig_handler; if (sigaction(sig, &sa, &osa) == 0) { - debug3_f("installing signal handler for %s, " - "previous %p", strsignal(sig), - osa.sa_handler); + if (!suppress_debug) + debug3_f("installed signal handler for" + " %s, previous 0x%p", + strsignal(sig), osa.sa_handler); saved_sighandler[sig] = osa.sa_handler; } } } if (unmasked) { - pselect_notify_setup(); + if ((ret = pselect_notify_setup()) == -1) { + saved_errno = ENOMEM; + goto out; + } pselect_notify_prepare(readfds); nfds = MAX(nfds, notify_pipe[0] + 1); } @@ -199,6 +176,25 @@ pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, if (unmasked) pselect_notify_done(readfds); + + out: + /* Restore signal handlers. */ + for (sig = 0; sig < _NSIG; sig++) { + if (saved_sighandler[sig] == NULL) + continue; + if (sigaction(sig, NULL, &sa) == 0) { + sa.sa_handler = saved_sighandler[sig]; + if (sigaction(sig, &sa, NULL) == 0) { + if (!suppress_debug) + debug3_f("restored signal handler for " + "%s", strsignal(sig)); + } else { + error_f("failed to restore signal handler for " + "%s: %s", strsignal(sig), strerror(errno)); + } + } + } + suppress_debug = 1; errno = saved_errno; return ret; } diff --git a/openbsd-compat/sha2.h b/openbsd-compat/bsd-sha2.h similarity index 100% rename from openbsd-compat/sha2.h rename to openbsd-compat/bsd-sha2.h diff --git a/openbsd-compat/daemon.c b/openbsd-compat/daemon.c index 3efe14c..2564669 100644 --- a/openbsd-compat/daemon.c +++ b/openbsd-compat/daemon.c @@ -36,9 +36,7 @@ #include -#ifdef HAVE_SYS_STAT_H -# include -#endif +#include #ifdef HAVE_FCNTL_H # include diff --git a/openbsd-compat/fake-rfc2553.c b/openbsd-compat/fake-rfc2553.c index d5a6297..5eaa479 100644 --- a/openbsd-compat/fake-rfc2553.c +++ b/openbsd-compat/fake-rfc2553.c @@ -94,13 +94,13 @@ gai_strerror(int err) case EAI_NODATA: return ("no address associated with name"); case EAI_MEMORY: - return ("memory allocation failure."); + return ("memory allocation failure"); case EAI_NONAME: - return ("nodename nor servname provided, or not known"); + return ("name or service is not known"); case EAI_FAMILY: return ("ai_family not supported"); default: - return ("unknown/invalid error."); + return ("unknown/invalid error"); } } #endif /* !HAVE_GAI_STRERROR */ diff --git a/openbsd-compat/glob.c b/openbsd-compat/glob.c index e891517..330b9c0 100644 --- a/openbsd-compat/glob.c +++ b/openbsd-compat/glob.c @@ -70,9 +70,7 @@ #include #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include diff --git a/openbsd-compat/memmem.c b/openbsd-compat/memmem.c index 2637401..afc20c6 100644 --- a/openbsd-compat/memmem.c +++ b/openbsd-compat/memmem.c @@ -30,9 +30,7 @@ #ifndef HAVE_MEMMEM #include -#ifdef HAVE_STDINT_H #include -#endif static char * twobyte_memmem(const unsigned char *h, size_t k, const unsigned char *n) diff --git a/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h index 0823d6a..680ba9d 100644 --- a/openbsd-compat/openbsd-compat.h +++ b/openbsd-compat/openbsd-compat.h @@ -43,7 +43,7 @@ #include "vis.h" #include "getrrsetbyname.h" #include "sha1.h" -#include "sha2.h" +#include "bsd-sha2.h" #include "md5.h" #include "blf.h" #include "fnmatch.h" diff --git a/openbsd-compat/openssl-compat.c b/openbsd-compat/openssl-compat.c index 1486507..e0cd472 100644 --- a/openbsd-compat/openssl-compat.c +++ b/openbsd-compat/openssl-compat.c @@ -32,7 +32,8 @@ #include "openssl-compat.h" /* - * OpenSSL version numbers: MNNFFPPS: major minor fix patch status + * OpenSSL version numbers: MNNFFPPS: major minor fix patch status. + * See the OpenSSL_version_num(3ssl) man page. * Versions >=3 require only major versions to match. * For versions <3, we accept compatible fix versions (so we allow 1.0.1 * to work with 1.0.0). Going backwards is only allowed within a patch series. @@ -49,10 +50,10 @@ ssh_compatible_openssl(long headerver, long libver) return 1; /* - * For versions >= 3.0, only the major and status must match. + * For versions >= 3.0, only the major must match. */ - if (headerver >= 0x3000000f) { - mask = 0xf000000fL; /* major,status */ + if (headerver >= 0x30000000) { + mask = 0xf0000000L; /* major only */ return (headerver & mask) == (libver & mask); } @@ -68,31 +69,22 @@ ssh_compatible_openssl(long headerver, long libver) return 0; } -void +int ssh_libcrypto_init(void) { -#if defined(HAVE_OPENSSL_INIT_CRYPTO) && \ - defined(OPENSSL_INIT_ADD_ALL_CIPHERS) && \ - defined(OPENSSL_INIT_ADD_ALL_DIGESTS) - OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS | - OPENSSL_INIT_ADD_ALL_DIGESTS, NULL); -#elif defined(HAVE_OPENSSL_ADD_ALL_ALGORITHMS) - OpenSSL_add_all_algorithms(); -#endif + uint64_t opts = OPENSSL_INIT_ADD_ALL_CIPHERS | + OPENSSL_INIT_ADD_ALL_DIGESTS; #ifdef USE_OPENSSL_ENGINE /* Enable use of crypto hardware */ ENGINE_load_builtin_engines(); ENGINE_register_all_complete(); - /* Load the libcrypto config file to pick up engines defined there */ -# if defined(HAVE_OPENSSL_INIT_CRYPTO) && defined(OPENSSL_INIT_LOAD_CONFIG) - OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS | - OPENSSL_INIT_ADD_ALL_DIGESTS | OPENSSL_INIT_LOAD_CONFIG, NULL); -# else - OPENSSL_config(NULL); -# endif + /* Tell libcrypto config file to pick up engines defined there */ + opts |= OPENSSL_INIT_LOAD_CONFIG; #endif /* USE_OPENSSL_ENGINE */ + + return OPENSSL_init_crypto(opts, NULL); } #ifndef HAVE_EVP_DIGESTSIGN diff --git a/openbsd-compat/openssl-compat.h b/openbsd-compat/openssl-compat.h index 2b9780f..42e2e28 100644 --- a/openbsd-compat/openssl-compat.h +++ b/openbsd-compat/openssl-compat.h @@ -23,15 +23,15 @@ #include #include #include +#include #include -#include #ifdef OPENSSL_HAS_ECC #include #endif #include int ssh_compatible_openssl(long, long); -void ssh_libcrypto_init(void); +int ssh_libcrypto_init(void); #if (OPENSSL_VERSION_NUMBER < 0x10100000L) # error OpenSSL 1.1.0 or greater is required @@ -45,9 +45,6 @@ void ssh_libcrypto_init(void); #ifndef OPENSSL_RSA_MAX_MODULUS_BITS # define OPENSSL_RSA_MAX_MODULUS_BITS 16384 #endif -#ifndef OPENSSL_DSA_MAX_MODULUS_BITS -# define OPENSSL_DSA_MAX_MODULUS_BITS 10000 -#endif #ifdef LIBRESSL_VERSION_NUMBER # if LIBRESSL_VERSION_NUMBER < 0x3010000fL @@ -55,15 +52,29 @@ void ssh_libcrypto_init(void); # endif #endif -#ifdef OPENSSL_IS_BORINGSSL +#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC) /* - * BoringSSL (rightly) got rid of the BN_FLG_CONSTTIME flag, along with + * BoringSSL and AWS-LC (rightly) got rid of the BN_FLG_CONSTTIME flag, along with * the entire BN_set_flags() interface. * https://boringssl.googlesource.com/boringssl/+/0a211dfe9 */ # define BN_set_flags(a, b) #endif +/* LibreSSL <3.4 has the _GFp variants but not the equivalent modern ones. */ +#ifndef HAVE_EC_POINT_GET_AFFINE_COORDINATES +# ifdef HAVE_EC_POINT_GET_AFFINE_COORDINATES_GFP +# define EC_POINT_get_affine_coordinates(a, b, c, d, e) \ + (EC_POINT_get_affine_coordinates_GFp(a, b, c, d, e)) +# endif +#endif +#ifndef HAVE_EC_POINT_SET_AFFINE_COORDINATES +# ifdef HAVE_EC_POINT_SET_AFFINE_COORDINATES_GFP +# define EC_POINT_set_affine_coordinates(a, b, c, d, e) \ + (EC_POINT_set_affine_coordinates_GFp(a, b, c, d, e)) +# endif +#endif + #ifndef HAVE_EVP_CIPHER_CTX_GET_IV # ifdef HAVE_EVP_CIPHER_CTX_GET_UPDATED_IV # define EVP_CIPHER_CTX_get_iv EVP_CIPHER_CTX_get_updated_iv diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c index 8adfec5..c1d54f3 100644 --- a/openbsd-compat/port-linux.c +++ b/openbsd-compat/port-linux.c @@ -319,6 +319,19 @@ oom_adjust_restore(void) } #endif /* LINUX_OOM_ADJUST */ +#ifdef LINUX_MEMLOCK_ONFAULT +#include + +void +memlock_onfault_setup(void) +{ + if (mlockall(MCL_CURRENT | MCL_FUTURE | MCL_ONFAULT) < 0) + verbose("unable to lock memory: %s", strerror(errno)); + else + debug("memory locked"); +} +#endif /* LINUX_MEMLOCK_ONFAULT */ + #ifdef SYSTEMD_NOTIFY static void ssh_systemd_notify(const char *, ...) diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h index 14064f8..959430d 100644 --- a/openbsd-compat/port-linux.h +++ b/openbsd-compat/port-linux.h @@ -30,6 +30,10 @@ void oom_adjust_restore(void); void oom_adjust_setup(void); #endif +#ifdef LINUX_MEMLOCK_ONFAULT +void memlock_onfault_setup(void); +#endif + #ifdef SYSTEMD_NOTIFY void ssh_systemd_notify_ready(void); void ssh_systemd_notify_reload(void); diff --git a/openbsd-compat/port-prngd.c b/openbsd-compat/port-prngd.c index 6afa8f9..ac4f270 100644 --- a/openbsd-compat/port-prngd.c +++ b/openbsd-compat/port-prngd.c @@ -26,9 +26,7 @@ #include #include -#ifdef HAVE_SYS_UN_H -# include -#endif +#include #include #include diff --git a/openbsd-compat/reallocarray.c b/openbsd-compat/reallocarray.c index 1a52acc..cffe9b5 100644 --- a/openbsd-compat/reallocarray.c +++ b/openbsd-compat/reallocarray.c @@ -22,9 +22,7 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include /* diff --git a/openbsd-compat/recallocarray.c b/openbsd-compat/recallocarray.c index 3e1156c..c281f75 100644 --- a/openbsd-compat/recallocarray.c +++ b/openbsd-compat/recallocarray.c @@ -22,9 +22,7 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include diff --git a/openbsd-compat/regress/utimensattest.c b/openbsd-compat/regress/utimensattest.c index bbc66c4..b4405e4 100644 --- a/openbsd-compat/regress/utimensattest.c +++ b/openbsd-compat/regress/utimensattest.c @@ -77,11 +77,17 @@ main(void) fail("utimensat", 0, 0); if (stat(TMPFILE, &sb) == -1) - fail("stat", 0, 0 ); + fail("stat", 0, 0); +#if 0 + /* + * This test only works on filesystems mounted 'noatime', otherwise the + * stat() above resets atime. Skip by default. + */ if (sb.st_atime != 12345678) - fail("st_atime", 0, 0 ); + fail("st_atime", 0, 0); +#endif if (sb.st_mtime != 34567890) - fail("st_mtime", 0, 0 ); + fail("st_mtime", 0, 0); #if 0 /* * Results expected to be rounded to the nearest microsecond. diff --git a/openbsd-compat/sha2.c b/openbsd-compat/sha2.c index 4f2ad8f..61941c6 100644 --- a/openbsd-compat/sha2.c +++ b/openbsd-compat/sha2.c @@ -45,7 +45,7 @@ #define MAKE_CLONE(x, y) void __ssh_compat_make_clone_##x_##y(void) #include -#include "openbsd-compat/sha2.h" +#include "openbsd-compat/bsd-sha2.h" /* * UNROLLED TRANSFORM LOOP NOTE: diff --git a/packet.c b/packet.c index 9dea2cf..190a579 100644 --- a/packet.c +++ b/packet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.c,v 1.318 2025/02/18 08:02:12 djm Exp $ */ +/* $OpenBSD: packet.c,v 1.334 2026/03/03 09:57:25 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -40,14 +40,11 @@ #include "includes.h" #include -#include "openbsd-compat/sys-queue.h" +#include #include -#ifdef HAVE_SYS_TIME_H -# include -#endif +#include #include -#include #include #include @@ -58,11 +55,10 @@ #include #include #include -#ifdef HAVE_POLL_H #include -#endif #include #include +#include /* * Explicitly include OpenSSL before zlib as some versions of OpenSSL have @@ -84,15 +80,12 @@ #include "compat.h" #include "ssh2.h" #include "cipher.h" -#include "sshkey.h" #include "kex.h" #include "digest.h" #include "mac.h" #include "log.h" #include "canohost.h" #include "misc.h" -#include "channels.h" -#include "ssh.h" #include "packet.h" #include "ssherr.h" #include "sshbuf.h" @@ -106,10 +99,10 @@ #define PACKET_MAX_SIZE (256 * 1024) struct packet_state { - u_int32_t seqnr; - u_int32_t packets; - u_int64_t blocks; - u_int64_t bytes; + uint32_t seqnr; + uint32_t packets; + uint64_t blocks; + uint64_t bytes; }; struct packet { @@ -187,10 +180,11 @@ struct session_state { struct packet_state p_read, p_send; /* Volume-based rekeying */ - u_int64_t max_blocks_in, max_blocks_out, rekey_limit; + uint64_t hard_max_blocks_in, hard_max_blocks_out; + uint64_t max_blocks_in, max_blocks_out, rekey_limit; /* Time-based rekeying */ - u_int32_t rekey_interval; /* how often in seconds */ + uint32_t rekey_interval; /* how often in seconds */ time_t rekey_time; /* time of last rekeying */ /* roundup current message to extra_pad bytes */ @@ -210,8 +204,8 @@ struct session_state { /* Used in ssh_packet_send_mux() */ int mux; - /* Used in packet_set_interactive */ - int set_interactive_called; + /* QoS handling */ + int qos_interactive, qos_other; /* Used in packet_set_maxsize */ int set_maxsize_called; @@ -219,6 +213,15 @@ struct session_state { /* One-off warning about weak ciphers */ int cipher_warning_done; + /* + * Disconnect in progress. Used to prevent reentry in + * ssh_packet_disconnect() + */ + int disconnecting; + + /* Nagle disabled on socket */ + int nodelay_set; + /* Hook for fuzzing inbound packets */ ssh_packet_hook_fn *hook_in; void *hook_in_ctx; @@ -247,6 +250,8 @@ ssh_alloc_session_state(void) state->connection_out = -1; state->max_packet_size = 32768; state->packet_timeout_ms = -1; + state->interactive_mode = 1; + state->qos_interactive = state->qos_other = -1; state->p_send.packets = state->p_read.packets = 0; state->initialized = 1; /* @@ -464,7 +469,7 @@ ssh_packet_connection_is_on_socket(struct ssh *ssh) } void -ssh_packet_get_bytes(struct ssh *ssh, u_int64_t *ibytes, u_int64_t *obytes) +ssh_packet_get_bytes(struct ssh *ssh, uint64_t *ibytes, uint64_t *obytes) { if (ibytes) *ibytes = ssh->state->p_read.bytes; @@ -675,6 +680,7 @@ ssh_packet_close_internal(struct ssh *ssh, int do_close) { struct session_state *state = ssh->state; u_int mode; + struct packet *p; if (!state->initialized) return; @@ -691,6 +697,11 @@ ssh_packet_close_internal(struct ssh *ssh, int do_close) sshbuf_free(state->output); sshbuf_free(state->outgoing_packet); sshbuf_free(state->incoming_packet); + while ((p = TAILQ_FIRST(&state->outgoing))) { + sshbuf_free(p->payload); + TAILQ_REMOVE(&state->outgoing, p, next); + free(p); + } for (mode = 0; mode < MODE_MAX; mode++) { kex_free_newkeys(state->newkeys[mode]); /* current keys */ state->newkeys[mode] = NULL; @@ -739,6 +750,13 @@ ssh_packet_close_internal(struct ssh *ssh, int do_close) } } +void +ssh_packet_free(struct ssh *ssh) +{ + ssh_packet_close_internal(ssh, 1); + freezero(ssh, sizeof(*ssh)); +} + void ssh_packet_close(struct ssh *ssh) { @@ -958,7 +976,7 @@ ssh_set_newkeys(struct ssh *ssh, int mode) struct sshcomp *comp; struct sshcipher_ctx **ccp; struct packet_state *ps; - u_int64_t *max_blocks; + uint64_t *max_blocks, *hard_max_blocks; const char *wmsg; int r, crypt_type; const char *dir = mode == MODE_OUT ? "out" : "in"; @@ -969,11 +987,13 @@ ssh_set_newkeys(struct ssh *ssh, int mode) ccp = &state->send_context; crypt_type = CIPHER_ENCRYPT; ps = &state->p_send; + hard_max_blocks = &state->hard_max_blocks_out; max_blocks = &state->max_blocks_out; } else { ccp = &state->receive_context; crypt_type = CIPHER_DECRYPT; ps = &state->p_read; + hard_max_blocks = &state->hard_max_blocks_in; max_blocks = &state->max_blocks_in; } if (state->newkeys[mode] != NULL) { @@ -1034,25 +1054,62 @@ ssh_set_newkeys(struct ssh *ssh, int mode) * See RFC4344 section 3.2. */ if (enc->block_size >= 16) - *max_blocks = (u_int64_t)1 << (enc->block_size*2); + *hard_max_blocks = (uint64_t)1 << (enc->block_size*2); else - *max_blocks = ((u_int64_t)1 << 30) / enc->block_size; - if (state->rekey_limit) + *hard_max_blocks = ((uint64_t)1 << 30) / enc->block_size; + *max_blocks = *hard_max_blocks; + if (state->rekey_limit) { *max_blocks = MINIMUM(*max_blocks, state->rekey_limit / enc->block_size); + } debug("rekey %s after %llu blocks", dir, (unsigned long long)*max_blocks); return 0; } #define MAX_PACKETS (1U<<31) +/* + * Checks whether the packet- or block- based rekeying limits have been + * exceeded. If the 'hard' flag is set, the checks are performed against the + * absolute maximum we're willing to accept for the given cipher. Otherwise + * the checks are performed against the RekeyLimit volume, which may be lower. + */ +static inline int +ssh_packet_check_rekey_blocklimit(struct ssh *ssh, u_int packet_len, int hard) +{ + struct session_state *state = ssh->state; + uint32_t out_blocks; + const uint64_t max_blocks_in = hard ? + state->hard_max_blocks_in : state->max_blocks_in; + const uint64_t max_blocks_out = hard ? + state->hard_max_blocks_out : state->max_blocks_out; + + /* + * Always rekey when MAX_PACKETS sent in either direction + * As per RFC4344 section 3.1 we do this after 2^31 packets. + */ + if (state->p_send.packets > MAX_PACKETS || + state->p_read.packets > MAX_PACKETS) + return 1; + + if (state->newkeys[MODE_OUT] == NULL) + return 0; + + /* Rekey after (cipher-specific) maximum blocks */ + out_blocks = ROUNDUP(packet_len, + state->newkeys[MODE_OUT]->enc.block_size); + return (max_blocks_out && + (state->p_send.blocks + out_blocks > max_blocks_out)) || + (max_blocks_in && + (state->p_read.blocks > max_blocks_in)); +} + static int ssh_packet_need_rekeying(struct ssh *ssh, u_int outbound_packet_len) { struct session_state *state = ssh->state; - u_int32_t out_blocks; - /* XXX client can't cope with rekeying pre-auth */ + /* Don't attempt rekeying during pre-auth */ if (!state->after_authentication) return 0; @@ -1060,10 +1117,6 @@ ssh_packet_need_rekeying(struct ssh *ssh, u_int outbound_packet_len) if (ssh_packet_is_rekeying(ssh)) return 0; - /* Peer can't rekey */ - if (ssh->compat & SSH_BUG_NOREKEY) - return 0; - /* * Permit one packet in or out per rekey - this allows us to * make progress when rekey limits are very small. @@ -1076,26 +1129,30 @@ ssh_packet_need_rekeying(struct ssh *ssh, u_int outbound_packet_len) (int64_t)state->rekey_time + state->rekey_interval <= monotime()) return 1; - /* - * Always rekey when MAX_PACKETS sent in either direction - * As per RFC4344 section 3.1 we do this after 2^31 packets. - */ - if (state->p_send.packets > MAX_PACKETS || - state->p_read.packets > MAX_PACKETS) - return 1; + return ssh_packet_check_rekey_blocklimit(ssh, outbound_packet_len, 0); +} - /* Rekey after (cipher-specific) maximum blocks */ - out_blocks = ROUNDUP(outbound_packet_len, - state->newkeys[MODE_OUT]->enc.block_size); - return (state->max_blocks_out && - (state->p_send.blocks + out_blocks > state->max_blocks_out)) || - (state->max_blocks_in && - (state->p_read.blocks > state->max_blocks_in)); +/* Checks that the hard rekey limits have not been exceeded during preauth */ +static int +ssh_packet_check_rekey_preauth(struct ssh *ssh, u_int outgoing_packet_len) +{ + if (ssh->state->after_authentication) + return 0; + + if (ssh_packet_check_rekey_blocklimit(ssh, 0, 1)) { + error("RekeyLimit exceeded before authentication completed"); + return SSH_ERR_NEED_REKEY; + } + return 0; } int ssh_packet_check_rekey(struct ssh *ssh) { + int r; + + if ((r = ssh_packet_check_rekey_preauth(ssh, 0)) != 0) + return r; if (!ssh_packet_need_rekeying(ssh, 0)) return 0; debug3_f("rekex triggered"); @@ -1306,8 +1363,7 @@ ssh_packet_send2_wrapped(struct ssh *ssh) logit("outgoing seqnr wraps around"); } if (++state->p_send.packets == 0) - if (!(ssh->compat & SSH_BUG_NOREKEY)) - return SSH_ERR_NEED_REKEY; + return SSH_ERR_NEED_REKEY; state->p_send.blocks += len / block_size; state->p_send.bytes += len; sshbuf_reset(state->outgoing_packet); @@ -1353,6 +1409,11 @@ ssh_packet_send2(struct ssh *ssh) need_rekey = !ssh_packet_type_is_kex(type) && ssh_packet_need_rekeying(ssh, sshbuf_len(state->outgoing_packet)); + /* Enforce hard rekey limit during pre-auth */ + if (!state->rekeying && !ssh_packet_type_is_kex(type) && + (r = ssh_packet_check_rekey_preauth(ssh, 0)) != 0) + return r; + /* * During rekeying we can only send key exchange messages. * Queue everything else. @@ -1424,7 +1485,7 @@ ssh_packet_send2(struct ssh *ssh) */ int -ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) +ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, uint32_t *seqnr_p) { struct session_state *state = ssh->state; int len, r, ms_remain = 0; @@ -1517,7 +1578,7 @@ ssh_packet_read(struct ssh *ssh) } static int -ssh_packet_read_poll2_mux(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) +ssh_packet_read_poll2_mux(struct ssh *ssh, u_char *typep, uint32_t *seqnr_p) { struct session_state *state = ssh->state; const u_char *cp; @@ -1555,7 +1616,7 @@ ssh_packet_read_poll2_mux(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) } int -ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) +ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, uint32_t *seqnr_p) { struct session_state *state = ssh->state; u_int padlen, need; @@ -1717,8 +1778,7 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) logit("incoming seqnr wraps around"); } if (++state->p_read.packets == 0) - if (!(ssh->compat & SSH_BUG_NOREKEY)) - return SSH_ERR_NEED_REKEY; + return SSH_ERR_NEED_REKEY; state->p_read.blocks += (state->packlen + 4) / block_size; state->p_read.bytes += state->packlen + 4; @@ -1793,7 +1853,7 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) } int -ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) +ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, uint32_t *seqnr_p) { struct session_state *state = ssh->state; u_int reason, seqnr; @@ -2064,12 +2124,12 @@ ssh_packet_disconnect(struct ssh *ssh, const char *fmt,...) { char buf[1024], remote_id[512]; va_list args; - static int disconnecting = 0; int r; - if (disconnecting) /* Guard against recursive invocations. */ + /* Guard against recursive invocations. */ + if (ssh->state->disconnecting) fatal("packet_disconnect called recursively."); - disconnecting = 1; + ssh->state->disconnecting = 1; /* * Format the message. Note that the caller must make sure the @@ -2206,41 +2266,41 @@ ssh_packet_interactive_data_to_write(struct ssh *ssh) sshbuf_len(ssh->state->output) < 256; } -void -ssh_packet_set_tos(struct ssh *ssh, int tos) +static void +apply_qos(struct ssh *ssh) { - if (!ssh_packet_connection_is_on_socket(ssh) || tos == INT_MAX) + struct session_state *state = ssh->state; + int qos = state->interactive_mode ? + state->qos_interactive : state->qos_other; + + if (!ssh_packet_connection_is_on_socket(ssh)) return; - set_sock_tos(ssh->state->connection_in, tos); + if (!state->nodelay_set) { + set_nodelay(state->connection_in); + state->nodelay_set = 1; + } + set_sock_tos(ssh->state->connection_in, qos); } -/* Informs that the current session is interactive. Sets IP flags for that. */ - +/* Informs that the current session is interactive. */ void -ssh_packet_set_interactive(struct ssh *ssh, int interactive, int qos_interactive, int qos_bulk) +ssh_packet_set_interactive(struct ssh *ssh, int interactive) { struct session_state *state = ssh->state; - if (state->set_interactive_called) - return; - state->set_interactive_called = 1; - - /* Record that we are in interactive mode. */ state->interactive_mode = interactive; - - /* Only set socket options if using a socket. */ - if (!ssh_packet_connection_is_on_socket(ssh)) - return; - set_nodelay(state->connection_in); - ssh_packet_set_tos(ssh, interactive ? qos_interactive : qos_bulk); + apply_qos(ssh); } -/* Returns true if the current connection is interactive. */ - -int -ssh_packet_is_interactive(struct ssh *ssh) +/* Set QoS flags to be used for interactive and non-interactive sessions */ +void +ssh_packet_set_qos(struct ssh *ssh, int qos_interactive, int qos_other) { - return ssh->state->interactive_mode; + struct session_state *state = ssh->state; + + state->qos_interactive = qos_interactive; + state->qos_other = qos_other; + apply_qos(ssh); } int @@ -2282,7 +2342,7 @@ ssh_packet_get_maxsize(struct ssh *ssh) } void -ssh_packet_set_rekey_limits(struct ssh *ssh, u_int64_t bytes, u_int32_t seconds) +ssh_packet_set_rekey_limits(struct ssh *ssh, uint64_t bytes, uint32_t seconds) { debug3("rekey after %llu bytes, %u seconds", (unsigned long long)bytes, (unsigned int)seconds); @@ -2415,6 +2475,7 @@ ssh_packet_get_state(struct ssh *ssh, struct sshbuf *m) struct session_state *state = ssh->state; int r; +#define ENCODE_INT(v) (((v) < 0) ? 0xFFFFFFFF : (u_int)v) if ((r = kex_to_blob(m, ssh->kex)) != 0 || (r = newkeys_to_blob(m, ssh, MODE_OUT)) != 0 || (r = newkeys_to_blob(m, ssh, MODE_IN)) != 0 || @@ -2429,9 +2490,12 @@ ssh_packet_get_state(struct ssh *ssh, struct sshbuf *m) (r = sshbuf_put_u32(m, state->p_read.packets)) != 0 || (r = sshbuf_put_u64(m, state->p_read.bytes)) != 0 || (r = sshbuf_put_stringb(m, state->input)) != 0 || - (r = sshbuf_put_stringb(m, state->output)) != 0) + (r = sshbuf_put_stringb(m, state->output)) != 0 || + (r = sshbuf_put_u32(m, ENCODE_INT(state->interactive_mode))) != 0 || + (r = sshbuf_put_u32(m, ENCODE_INT(state->qos_interactive))) != 0 || + (r = sshbuf_put_u32(m, ENCODE_INT(state->qos_other))) != 0) return r; - +#undef ENCODE_INT return 0; } @@ -2550,6 +2614,7 @@ ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m) const u_char *input, *output; size_t ilen, olen; int r; + u_int interactive, qos_interactive, qos_other; if ((r = kex_from_blob(m, &ssh->kex)) != 0 || (r = newkeys_from_blob(m, ssh, MODE_OUT)) != 0 || @@ -2586,6 +2651,16 @@ ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m) (r = sshbuf_put(state->output, output, olen)) != 0) return r; + if ((r = sshbuf_get_u32(m, &interactive)) != 0 || + (r = sshbuf_get_u32(m, &qos_interactive)) != 0 || + (r = sshbuf_get_u32(m, &qos_other)) != 0) + return r; +#define DECODE_INT(v) ((v) > INT_MAX ? -1 : (int)(v)) + state->interactive_mode = DECODE_INT(interactive); + state->qos_interactive = DECODE_INT(qos_interactive); + state->qos_other = DECODE_INT(qos_other); +#undef DECODE_INT + if (sshbuf_len(m)) return SSH_ERR_INVALID_FORMAT; debug3_f("done"); @@ -2615,13 +2690,13 @@ sshpkt_put_u8(struct ssh *ssh, u_char val) } int -sshpkt_put_u32(struct ssh *ssh, u_int32_t val) +sshpkt_put_u32(struct ssh *ssh, uint32_t val) { return sshbuf_put_u32(ssh->state->outgoing_packet, val); } int -sshpkt_put_u64(struct ssh *ssh, u_int64_t val) +sshpkt_put_u64(struct ssh *ssh, uint64_t val) { return sshbuf_put_u64(ssh->state->outgoing_packet, val); } @@ -2681,13 +2756,13 @@ sshpkt_get_u8(struct ssh *ssh, u_char *valp) } int -sshpkt_get_u32(struct ssh *ssh, u_int32_t *valp) +sshpkt_get_u32(struct ssh *ssh, uint32_t *valp) { return sshbuf_get_u32(ssh->state->incoming_packet, valp); } int -sshpkt_get_u64(struct ssh *ssh, u_int64_t *valp) +sshpkt_get_u64(struct ssh *ssh, uint64_t *valp) { return sshbuf_get_u64(ssh->state->incoming_packet, valp); } @@ -2812,7 +2887,7 @@ ssh_packet_send_mux(struct ssh *ssh) int sshpkt_msg_ignore(struct ssh *ssh, u_int nbytes) { - u_int32_t rnd = 0; + uint32_t rnd = 0; int r; u_int i; @@ -2867,3 +2942,165 @@ sshpkt_add_padding(struct ssh *ssh, u_char pad) ssh->state->extra_pad = pad; return 0; } + +static char * +format_traffic_stats(struct packet_state *ps) +{ + char *stats = NULL, bytes[FMT_SCALED_STRSIZE]; + + if (ps->bytes > LLONG_MAX || fmt_scaled(ps->bytes, bytes) != 0) + strlcpy(bytes, "OVERFLOW", sizeof(bytes)); + + xasprintf(&stats, "%lu pkts %llu blks %sB", + (unsigned long)ps->packets, (unsigned long long)ps->blocks, bytes); + return stats; +} + +static char * +dedupe_alg_names(const char *in, const char *out) +{ + char *names = NULL; + + if (in == NULL) + in = ""; + if (out == NULL) + out = ""; + + if (strcmp(in, out) == 0) { + names = xstrdup(in); + } else { + xasprintf(&names, "%s in, %s out", in, out); + } + return names; +} + +static char * +comp_status_message(struct ssh *ssh) +{ +#ifdef WITH_ZLIB + char *ret = NULL; + struct session_state *state = ssh->state; + unsigned long long iraw = 0, icmp = 0, oraw = 0, ocmp = 0; + char iraw_f[FMT_SCALED_STRSIZE] = "", oraw_f[FMT_SCALED_STRSIZE] = ""; + char icmp_f[FMT_SCALED_STRSIZE] = "", ocmp_f[FMT_SCALED_STRSIZE] = ""; + + if (state->compression_buffer) { + if (state->compression_in_started) { + iraw = state->compression_in_stream.total_out; + icmp = state->compression_in_stream.total_in; + if (fmt_scaled(iraw, iraw_f) != 0) + strlcpy(iraw_f, "OVERFLOW", sizeof(iraw_f)); + if (fmt_scaled(icmp, icmp_f) != 0) + strlcpy(icmp_f, "OVERFLOW", sizeof(icmp_f)); + } + if (state->compression_out_started) { + oraw = state->compression_out_stream.total_in; + ocmp = state->compression_out_stream.total_out; + if (fmt_scaled(oraw, oraw_f) != 0) + strlcpy(oraw_f, "OVERFLOW", sizeof(oraw_f)); + if (fmt_scaled(ocmp, ocmp_f) != 0) + strlcpy(ocmp_f, "OVERFLOW", sizeof(ocmp_f)); + } + xasprintf(&ret, + " compressed %s/%s (*%.3f) in," + " %s/%s (*%.3f) out\r\n", + icmp_f, iraw_f, iraw == 0 ? 0.0 : (double)icmp / iraw, + ocmp_f, oraw_f, oraw == 0 ? 0.0 : (double)ocmp / oraw); + return ret; + } +#endif /* WITH_ZLIB */ + return xstrdup(""); +} + +char * +connection_info_message(struct ssh *ssh) +{ + char *ret = NULL, *cipher = NULL, *mac = NULL, *comp = NULL; + char *rekey_volume = NULL, *rekey_time = NULL, *comp_info = NULL; + char thishost[NI_MAXHOST] = "unknown", *tcp_info = NULL; + struct kex *kex; + struct session_state *state; + struct newkeys *nk_in, *nk_out; + char *stats_in = NULL, *stats_out = NULL; + uint64_t epoch = (uint64_t)time(NULL) - monotime(); + + if (ssh == NULL) + return NULL; + state = ssh->state; + kex = ssh->kex; + + (void)gethostname(thishost, sizeof(thishost)); + + if (ssh_local_port(ssh) != 65535 || + strcmp(ssh_local_ipaddr(ssh), "UNKNOWN") != 0) { + xasprintf(&tcp_info, " tcp %s:%d -> %s:%d\r\n", + ssh_local_ipaddr(ssh), ssh_local_port(ssh), + ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); + } else { + tcp_info = xstrdup(""); + } + + nk_in = ssh->state->newkeys[MODE_IN]; + nk_out = ssh->state->newkeys[MODE_OUT]; + stats_in = format_traffic_stats(&ssh->state->p_read); + stats_out = format_traffic_stats(&ssh->state->p_send); + + cipher = dedupe_alg_names(nk_in->enc.name, nk_out->enc.name); + mac = dedupe_alg_names(nk_in->mac.name, nk_out->mac.name); + comp = dedupe_alg_names(nk_in->comp.name, nk_out->comp.name); + + /* Volume based rekeying. */ + if (state->rekey_limit == 0) { + xasprintf(&rekey_volume, "limit none"); + } else { + char *volumes = NULL, in[32], out[32]; + + snprintf(in, sizeof(in), "%llu", + (unsigned long long)state->max_blocks_in); + snprintf(out, sizeof(out), "%llu", + (unsigned long long)state->max_blocks_out); + volumes = dedupe_alg_names(in, out); + xasprintf(&rekey_volume, "limit blocks %s", volumes); + free(volumes); + } + + /* Time based rekeying. */ + if (state->rekey_interval == 0) { + rekey_time = xstrdup("interval none"); + } else { + char rekey_next[64]; + + format_absolute_time(epoch + state->rekey_time + + state->rekey_interval, rekey_next, sizeof(rekey_next)); + xasprintf(&rekey_time, "interval %s, next %s", + fmt_timeframe(state->rekey_interval), rekey_next); + } + comp_info = comp_status_message(ssh); + + xasprintf(&ret, "Connection information for %s pid %lld\r\n" + "%s" + " kexalgorithm %s\r\n hostkeyalgorithm %s\r\n" + " cipher %s\r\n mac %s\r\n compression %s\r\n" + " rekey %s %s\r\n" + " traffic %s in, %s out\r\n" + "%s", + thishost, (long long)getpid(), + tcp_info, + kex->name, kex->hostkey_alg, + cipher, mac, comp, + rekey_volume, rekey_time, + stats_in, stats_out, + comp_info + ); + free(tcp_info); + free(cipher); + free(mac); + free(comp); + free(stats_in); + free(stats_out); + free(rekey_volume); + free(rekey_time); + free(comp_info); + return ret; +} + diff --git a/packet.h b/packet.h index 49bb87f..3e8acb2 100644 --- a/packet.h +++ b/packet.h @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.h,v 1.99 2024/08/15 00:51:51 djm Exp $ */ +/* $OpenBSD: packet.h,v 1.107 2026/03/03 09:57:25 dtucker Exp $ */ /* * Author: Tatu Ylonen @@ -16,6 +16,10 @@ #ifndef PACKET_H #define PACKET_H +#include + +#include +#include #include #ifdef WITH_OPENSSL @@ -36,9 +40,6 @@ # define EVP_PKEY void #endif /* WITH_OPENSSL */ -#include -#include "openbsd-compat/sys-queue.h" - struct kex; struct sshkey; struct sshbuf; @@ -74,7 +75,7 @@ struct ssh { int dispatch_skip_packets; /* datafellows */ - int compat; + uint32_t compat; /* Lists for private and public keys */ TAILQ_HEAD(, key_entry) private_keys; @@ -101,6 +102,7 @@ int ssh_packet_connection_af(struct ssh *); void ssh_packet_set_nonblocking(struct ssh *); int ssh_packet_get_connection_in(struct ssh *); int ssh_packet_get_connection_out(struct ssh *); +void ssh_packet_free(struct ssh *); void ssh_packet_close(struct ssh *); void ssh_packet_set_input_hook(struct ssh *, ssh_packet_hook_fn *, void *); void ssh_packet_clear_keys(struct ssh *); @@ -110,9 +112,8 @@ int ssh_packet_is_rekeying(struct ssh *); int ssh_packet_check_rekey(struct ssh *); void ssh_packet_set_protocol_flags(struct ssh *, u_int); u_int ssh_packet_get_protocol_flags(struct ssh *); -void ssh_packet_set_tos(struct ssh *, int); -void ssh_packet_set_interactive(struct ssh *, int, int, int); -int ssh_packet_is_interactive(struct ssh *); +void ssh_packet_set_interactive(struct ssh *, int); +void ssh_packet_set_qos(struct ssh *, int, int); void ssh_packet_set_server(struct ssh *); void ssh_packet_set_authenticated(struct ssh *); void ssh_packet_set_mux(struct ssh *); @@ -126,11 +127,11 @@ int ssh_packet_send2_wrapped(struct ssh *); int ssh_packet_send2(struct ssh *); int ssh_packet_read(struct ssh *); -int ssh_packet_read_poll2(struct ssh *, u_char *, u_int32_t *seqnr_p); +int ssh_packet_read_poll2(struct ssh *, u_char *, uint32_t *seqnr_p); int ssh_packet_process_incoming(struct ssh *, const char *buf, u_int len); int ssh_packet_process_read(struct ssh *, int); -int ssh_packet_read_seqnr(struct ssh *, u_char *, u_int32_t *seqnr_p); -int ssh_packet_read_poll_seqnr(struct ssh *, u_char *, u_int32_t *seqnr_p); +int ssh_packet_read_seqnr(struct ssh *, u_char *, uint32_t *seqnr_p); +int ssh_packet_read_poll_seqnr(struct ssh *, u_char *, uint32_t *seqnr_p); void ssh_packet_disconnect(struct ssh *, const char *fmt, ...) __attribute__((format(printf, 2, 3))) @@ -138,7 +139,7 @@ void ssh_packet_disconnect(struct ssh *, const char *fmt, ...) void ssh_packet_send_debug(struct ssh *, const char *fmt, ...) __attribute__((format(printf, 2, 3))); int ssh_set_newkeys(struct ssh *, int mode); -void ssh_packet_get_bytes(struct ssh *, u_int64_t *, u_int64_t *); +void ssh_packet_get_bytes(struct ssh *, uint64_t *, uint64_t *); int ssh_packet_write_poll(struct ssh *); int ssh_packet_write_wait(struct ssh *); @@ -167,7 +168,7 @@ int ssh_local_port(struct ssh *); const char *ssh_packet_rdomain_in(struct ssh *); char *ssh_remote_hostname(struct ssh *); -void ssh_packet_set_rekey_limits(struct ssh *, u_int64_t, u_int32_t); +void ssh_packet_set_rekey_limits(struct ssh *, uint64_t, uint32_t); time_t ssh_packet_get_rekey_timeout(struct ssh *); void *ssh_packet_get_input(struct ssh *); @@ -187,8 +188,8 @@ int sshpkt_msg_ignore(struct ssh *, u_int); int sshpkt_put(struct ssh *ssh, const void *v, size_t len); int sshpkt_putb(struct ssh *ssh, const struct sshbuf *b); int sshpkt_put_u8(struct ssh *ssh, u_char val); -int sshpkt_put_u32(struct ssh *ssh, u_int32_t val); -int sshpkt_put_u64(struct ssh *ssh, u_int64_t val); +int sshpkt_put_u32(struct ssh *ssh, uint32_t val); +int sshpkt_put_u64(struct ssh *ssh, uint64_t val); int sshpkt_put_string(struct ssh *ssh, const void *v, size_t len); int sshpkt_put_cstring(struct ssh *ssh, const void *v); int sshpkt_put_stringb(struct ssh *ssh, const struct sshbuf *v); @@ -198,8 +199,8 @@ int sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v); int sshpkt_get(struct ssh *ssh, void *valp, size_t len); int sshpkt_get_u8(struct ssh *ssh, u_char *valp); -int sshpkt_get_u32(struct ssh *ssh, u_int32_t *valp); -int sshpkt_get_u64(struct ssh *ssh, u_int64_t *valp); +int sshpkt_get_u32(struct ssh *ssh, uint32_t *valp); +int sshpkt_get_u64(struct ssh *ssh, uint64_t *valp); int sshpkt_get_string(struct ssh *ssh, u_char **valp, size_t *lenp); int sshpkt_get_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp); int sshpkt_peek_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp); @@ -210,6 +211,7 @@ int sshpkt_get_bignum2(struct ssh *ssh, BIGNUM **valp); int sshpkt_get_end(struct ssh *ssh); void sshpkt_fmt_connection_id(struct ssh *ssh, char *s, size_t l); const u_char *sshpkt_ptr(struct ssh *, size_t *lenp); +char *connection_info_message(struct ssh *ssh); #if !defined(WITH_OPENSSL) # undef BIGNUM diff --git a/pathnames.h b/pathnames.h index 61c5f84..ae01c69 100644 --- a/pathnames.h +++ b/pathnames.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pathnames.h,v 1.32 2024/05/17 00:30:24 djm Exp $ */ +/* $OpenBSD: pathnames.h,v 1.36 2025/08/29 03:50:38 djm Exp $ */ /* * Author: Tatu Ylonen @@ -36,11 +36,9 @@ */ #define _PATH_SERVER_CONFIG_FILE SSHDIR "/sshd_config" #define _PATH_HOST_CONFIG_FILE SSHDIR "/ssh_config" -#define _PATH_HOST_DSA_KEY_FILE SSHDIR "/ssh_host_dsa_key" #define _PATH_HOST_ECDSA_KEY_FILE SSHDIR "/ssh_host_ecdsa_key" -#define _PATH_HOST_ED25519_KEY_FILE SSHDIR "/ssh_host_ed25519_key" -#define _PATH_HOST_XMSS_KEY_FILE SSHDIR "/ssh_host_xmss_key" #define _PATH_HOST_RSA_KEY_FILE SSHDIR "/ssh_host_rsa_key" +#define _PATH_HOST_ED25519_KEY_FILE SSHDIR "/ssh_host_ed25519_key" #define _PATH_DH_MODULI SSHDIR "/moduli" #ifndef _PATH_SSH_PROGRAM @@ -51,6 +49,9 @@ #ifndef _PATH_SSHD_SESSION #define _PATH_SSHD_SESSION "/usr/libexec/sshd-session" #endif +#ifndef _PATH_SSHD_AUTH +#define _PATH_SSHD_AUTH "/usr/libexec/sshd-auth" +#endif /* * The process id of the daemon listening for connections is saved here to @@ -64,6 +65,13 @@ */ #define _PATH_SSH_USER_DIR ".ssh" + +/* + * The directory in which ssh-agent sockets and agent sockets forwarded by + * sshd reside. This directory should not be world-readable. + */ +#define _PATH_SSH_AGENT_SOCKET_DIR _PATH_SSH_USER_DIR "/agent" + /* * Per-user file containing host keys of known hosts. This file need not be * readable by anyone except the user him/herself, though this does not @@ -77,11 +85,9 @@ * Name of the default file containing client-side authentication key. This * file should only be readable by the user him/herself. */ -#define _PATH_SSH_CLIENT_ID_DSA _PATH_SSH_USER_DIR "/id_dsa" #define _PATH_SSH_CLIENT_ID_ECDSA _PATH_SSH_USER_DIR "/id_ecdsa" #define _PATH_SSH_CLIENT_ID_RSA _PATH_SSH_USER_DIR "/id_rsa" #define _PATH_SSH_CLIENT_ID_ED25519 _PATH_SSH_USER_DIR "/id_ed25519" -#define _PATH_SSH_CLIENT_ID_XMSS _PATH_SSH_USER_DIR "/id_xmss" #define _PATH_SSH_CLIENT_ID_ECDSA_SK _PATH_SSH_USER_DIR "/id_ecdsa_sk" #define _PATH_SSH_CLIENT_ID_ED25519_SK _PATH_SSH_USER_DIR "/id_ed25519_sk" @@ -163,6 +169,9 @@ #ifndef _PATH_SFTP_SERVER #define _PATH_SFTP_SERVER "/usr/libexec/sftp-server" #endif +#ifndef _PATH_LS +#define _PATH_LS "ls" +#endif /* chroot directory for unprivileged user when UsePrivilegeSeparation=yes */ #ifndef _PATH_PRIVSEP_CHROOT_DIR @@ -171,11 +180,7 @@ /* for passwd change */ #ifndef _PATH_PASSWD_PROG -#define _PATH_PASSWD_PROG "/usr/bin/passwd" -#endif - -#ifndef _PATH_LS -#define _PATH_LS "ls" +#define _PATH_PASSWD_PROG "/usr/bin/passwd" #endif /* Askpass program define */ diff --git a/pkcs11.h b/pkcs11.h index b01d58f..707333f 100644 --- a/pkcs11.h +++ b/pkcs11.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pkcs11.h,v 1.3 2013/11/26 19:15:09 deraadt Exp $ */ +/* $OpenBSD: pkcs11.h,v 1.4 2025/07/25 13:06:07 djm Exp $ */ /* pkcs11.h Copyright 2006, 2007 g10 Code GmbH Copyright 2006 Andreas Jellinghaus @@ -64,9 +64,9 @@ extern "C" { version of this file, please consider deleting the revision macro (you may use a macro with a different name to keep track of your versions). */ -#define CRYPTOKI_VERSION_MAJOR 2 -#define CRYPTOKI_VERSION_MINOR 20 -#define CRYPTOKI_VERSION_REVISION 6 +#define CRYPTOKI_VERSION_MAJOR 3 +#define CRYPTOKI_VERSION_MINOR 0 +#define CRYPTOKI_VERSION_REVISION 0 /* Compatibility interface is default, unless CRYPTOKI_GNU is @@ -96,7 +96,6 @@ extern "C" { #endif - #ifdef CRYPTOKI_COMPAT /* If we are in compatibility mode, switch all exposed names to the PKCS #11 variant. There are corresponding #undefs below. */ @@ -155,6 +154,8 @@ extern "C" { #define ck_mechanism_type_t CK_MECHANISM_TYPE +#define ck_rsa_pkcs_mgf_type_t CK_RSA_PKCS_MGF_TYPE + #define ck_mechanism _CK_MECHANISM #define parameter pParameter #define parameter_len ulParameterLen @@ -166,7 +167,10 @@ extern "C" { #define ck_rv_t CK_RV #define ck_notify_t CK_NOTIFY +#define ck_interface CK_INTERFACE + #define ck_function_list _CK_FUNCTION_LIST +#define ck_function_list_3_0 _CK_FUNCTION_LIST_3_0 #define ck_createmutex_t CK_CREATEMUTEX #define ck_destroymutex_t CK_DESTROYMUTEX @@ -183,7 +187,6 @@ extern "C" { #endif /* CRYPTOKI_COMPAT */ - typedef unsigned long ck_flags_t; struct ck_version @@ -205,7 +208,7 @@ struct ck_info typedef unsigned long ck_notification_t; -#define CKN_SURRENDER (0) +#define CKN_SURRENDER (0UL) typedef unsigned long ck_slot_id_t; @@ -221,10 +224,10 @@ struct ck_slot_info }; -#define CKF_TOKEN_PRESENT (1 << 0) -#define CKF_REMOVABLE_DEVICE (1 << 1) -#define CKF_HW_SLOT (1 << 2) -#define CKF_ARRAY_ATTRIBUTE (1 << 30) +#define CKF_TOKEN_PRESENT (1UL << 0) +#define CKF_REMOVABLE_DEVICE (1UL << 1) +#define CKF_HW_SLOT (1UL << 2) +#define CKF_ARRAY_ATTRIBUTE (1UL << 30) struct ck_token_info @@ -250,48 +253,48 @@ struct ck_token_info }; -#define CKF_RNG (1 << 0) -#define CKF_WRITE_PROTECTED (1 << 1) -#define CKF_LOGIN_REQUIRED (1 << 2) -#define CKF_USER_PIN_INITIALIZED (1 << 3) -#define CKF_RESTORE_KEY_NOT_NEEDED (1 << 5) -#define CKF_CLOCK_ON_TOKEN (1 << 6) -#define CKF_PROTECTED_AUTHENTICATION_PATH (1 << 8) -#define CKF_DUAL_CRYPTO_OPERATIONS (1 << 9) -#define CKF_TOKEN_INITIALIZED (1 << 10) -#define CKF_SECONDARY_AUTHENTICATION (1 << 11) -#define CKF_USER_PIN_COUNT_LOW (1 << 16) -#define CKF_USER_PIN_FINAL_TRY (1 << 17) -#define CKF_USER_PIN_LOCKED (1 << 18) -#define CKF_USER_PIN_TO_BE_CHANGED (1 << 19) -#define CKF_SO_PIN_COUNT_LOW (1 << 20) -#define CKF_SO_PIN_FINAL_TRY (1 << 21) -#define CKF_SO_PIN_LOCKED (1 << 22) -#define CKF_SO_PIN_TO_BE_CHANGED (1 << 23) +#define CKF_RNG (1UL << 0) +#define CKF_WRITE_PROTECTED (1UL << 1) +#define CKF_LOGIN_REQUIRED (1UL << 2) +#define CKF_USER_PIN_INITIALIZED (1UL << 3) +#define CKF_RESTORE_KEY_NOT_NEEDED (1UL << 5) +#define CKF_CLOCK_ON_TOKEN (1UL << 6) +#define CKF_PROTECTED_AUTHENTICATION_PATH (1UL << 8) +#define CKF_DUAL_CRYPTO_OPERATIONS (1UL << 9) +#define CKF_TOKEN_INITIALIZED (1UL << 10) +#define CKF_SECONDARY_AUTHENTICATION (1UL << 11) +#define CKF_USER_PIN_COUNT_LOW (1UL << 16) +#define CKF_USER_PIN_FINAL_TRY (1UL << 17) +#define CKF_USER_PIN_LOCKED (1UL << 18) +#define CKF_USER_PIN_TO_BE_CHANGED (1UL << 19) +#define CKF_SO_PIN_COUNT_LOW (1UL << 20) +#define CKF_SO_PIN_FINAL_TRY (1UL << 21) +#define CKF_SO_PIN_LOCKED (1UL << 22) +#define CKF_SO_PIN_TO_BE_CHANGED (1UL << 23) #define CK_UNAVAILABLE_INFORMATION ((unsigned long) -1) -#define CK_EFFECTIVELY_INFINITE (0) +#define CK_EFFECTIVELY_INFINITE (0UL) typedef unsigned long ck_session_handle_t; -#define CK_INVALID_HANDLE (0) +#define CK_INVALID_HANDLE (0UL) typedef unsigned long ck_user_type_t; -#define CKU_SO (0) -#define CKU_USER (1) -#define CKU_CONTEXT_SPECIFIC (2) +#define CKU_SO (0UL) +#define CKU_USER (1UL) +#define CKU_CONTEXT_SPECIFIC (2UL) typedef unsigned long ck_state_t; -#define CKS_RO_PUBLIC_SESSION (0) -#define CKS_RO_USER_FUNCTIONS (1) -#define CKS_RW_PUBLIC_SESSION (2) -#define CKS_RW_USER_FUNCTIONS (3) -#define CKS_RW_SO_FUNCTIONS (4) +#define CKS_RO_PUBLIC_SESSION (0UL) +#define CKS_RO_USER_FUNCTIONS (1UL) +#define CKS_RW_PUBLIC_SESSION (2UL) +#define CKS_RW_USER_FUNCTIONS (3UL) +#define CKS_RW_SO_FUNCTIONS (4UL) struct ck_session_info @@ -302,8 +305,8 @@ struct ck_session_info unsigned long device_error; }; -#define CKF_RW_SESSION (1 << 1) -#define CKF_SERIAL_SESSION (1 << 2) +#define CKF_RW_SESSION (1UL << 1) +#define CKF_SERIAL_SESSION (1UL << 2) typedef unsigned long ck_object_handle_t; @@ -311,149 +314,194 @@ typedef unsigned long ck_object_handle_t; typedef unsigned long ck_object_class_t; -#define CKO_DATA (0) -#define CKO_CERTIFICATE (1) -#define CKO_PUBLIC_KEY (2) -#define CKO_PRIVATE_KEY (3) -#define CKO_SECRET_KEY (4) -#define CKO_HW_FEATURE (5) -#define CKO_DOMAIN_PARAMETERS (6) -#define CKO_MECHANISM (7) -#define CKO_VENDOR_DEFINED (1U << 31) - +#define CKO_DATA (0UL) +#define CKO_CERTIFICATE (1UL) +#define CKO_PUBLIC_KEY (2UL) +#define CKO_PRIVATE_KEY (3UL) +#define CKO_SECRET_KEY (4UL) +#define CKO_HW_FEATURE (5UL) +#define CKO_DOMAIN_PARAMETERS (6UL) +#define CKO_MECHANISM (7UL) +#define CKO_OTP_KEY (8UL) +#define CKO_PROFILE (9UL) +#define CKO_VENDOR_DEFINED (1UL << 31) + +#define CKP_INVALID_ID (0UL) +#define CKP_BASELINE_PROVIDER (1UL) +#define CKP_EXTENDED_PROVIDER (2UL) +#define CKP_AUTHENTICATION_TOKEN (3UL) +#define CKP_PUBLIC_CERTIFICATES_TOKEN (4UL) +#define CKP_VENDOR_DEFINED (1UL << 31) typedef unsigned long ck_hw_feature_type_t; -#define CKH_MONOTONIC_COUNTER (1) -#define CKH_CLOCK (2) -#define CKH_USER_INTERFACE (3) -#define CKH_VENDOR_DEFINED (1U << 31) +#define CKH_MONOTONIC_COUNTER (1UL) +#define CKH_CLOCK (2UL) +#define CKH_USER_INTERFACE (3UL) +#define CKH_VENDOR_DEFINED (1UL << 31) typedef unsigned long ck_key_type_t; -#define CKK_RSA (0) -#define CKK_DSA (1) -#define CKK_DH (2) -#define CKK_ECDSA (3) -#define CKK_EC (3) -#define CKK_X9_42_DH (4) -#define CKK_KEA (5) -#define CKK_GENERIC_SECRET (0x10) -#define CKK_RC2 (0x11) -#define CKK_RC4 (0x12) -#define CKK_DES (0x13) -#define CKK_DES2 (0x14) -#define CKK_DES3 (0x15) -#define CKK_CAST (0x16) -#define CKK_CAST3 (0x17) -#define CKK_CAST128 (0x18) -#define CKK_RC5 (0x19) -#define CKK_IDEA (0x1a) -#define CKK_SKIPJACK (0x1b) -#define CKK_BATON (0x1c) -#define CKK_JUNIPER (0x1d) -#define CKK_CDMF (0x1e) -#define CKK_AES (0x1f) -#define CKK_BLOWFISH (0x20) -#define CKK_TWOFISH (0x21) -#define CKK_VENDOR_DEFINED (1U << 31) +#define CKK_RSA (0UL) +#define CKK_DSA (1UL) +#define CKK_DH (2UL) +#define CKK_ECDSA (3UL) +#define CKK_EC (3UL) +#define CKK_X9_42_DH (4UL) +#define CKK_KEA (5UL) +#define CKK_GENERIC_SECRET (0x10UL) +#define CKK_RC2 (0x11UL) +#define CKK_RC4 (0x12UL) +#define CKK_DES (0x13UL) +#define CKK_DES2 (0x14UL) +#define CKK_DES3 (0x15UL) +#define CKK_CAST (0x16UL) +#define CKK_CAST3 (0x17UL) +#define CKK_CAST128 (0x18UL) +#define CKK_RC5 (0x19UL) +#define CKK_IDEA (0x1aUL) +#define CKK_SKIPJACK (0x1bUL) +#define CKK_BATON (0x1cUL) +#define CKK_JUNIPER (0x1dUL) +#define CKK_CDMF (0x1eUL) +#define CKK_AES (0x1fUL) +#define CKK_BLOWFISH (0x20UL) +#define CKK_TWOFISH (0x21UL) +#define CKK_GOSTR3410 (0x30UL) +#define CKK_GOSTR3411 (0x31UL) +#define CKK_GOST28147 (0x32UL) +#define CKK_EC_EDWARDS (0x40UL) +#define CKK_EC_MONTGOMERY (0x41UL) +#define CKK_HKDF (0x42UL) +#define CKK_VENDOR_DEFINED (1UL << 31) + +/* + * A mask for new GOST algorithms. + * For details visit https://tc26.ru/standarts/perevody/guidelines-the-pkcs-11-extensions-for-implementing-the-gost-r-34-10-2012-and-gost-r-34-11-2012-russian-standards-.html + */ +#define NSSCK_VENDOR_PKCS11_RU_TEAM (CKK_VENDOR_DEFINED | 0x54321000) +#define CK_VENDOR_PKCS11_RU_TEAM_TK26 NSSCK_VENDOR_PKCS11_RU_TEAM + +#define CKK_GOSTR3410_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x003) typedef unsigned long ck_certificate_type_t; -#define CKC_X_509 (0) -#define CKC_X_509_ATTR_CERT (1) -#define CKC_WTLS (2) -#define CKC_VENDOR_DEFINED (1U << 31) +#define CKC_X_509 (0UL) +#define CKC_X_509_ATTR_CERT (1UL) +#define CKC_WTLS (2UL) +#define CKC_VENDOR_DEFINED (1UL << 31) typedef unsigned long ck_attribute_type_t; -#define CKA_CLASS (0) -#define CKA_TOKEN (1) -#define CKA_PRIVATE (2) -#define CKA_LABEL (3) -#define CKA_APPLICATION (0x10) -#define CKA_VALUE (0x11) -#define CKA_OBJECT_ID (0x12) -#define CKA_CERTIFICATE_TYPE (0x80) -#define CKA_ISSUER (0x81) -#define CKA_SERIAL_NUMBER (0x82) -#define CKA_AC_ISSUER (0x83) -#define CKA_OWNER (0x84) -#define CKA_ATTR_TYPES (0x85) -#define CKA_TRUSTED (0x86) -#define CKA_CERTIFICATE_CATEGORY (0x87) -#define CKA_JAVA_MIDP_SECURITY_DOMAIN (0x88) -#define CKA_URL (0x89) -#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY (0x8a) -#define CKA_HASH_OF_ISSUER_PUBLIC_KEY (0x8b) -#define CKA_CHECK_VALUE (0x90) -#define CKA_KEY_TYPE (0x100) -#define CKA_SUBJECT (0x101) -#define CKA_ID (0x102) -#define CKA_SENSITIVE (0x103) -#define CKA_ENCRYPT (0x104) -#define CKA_DECRYPT (0x105) -#define CKA_WRAP (0x106) -#define CKA_UNWRAP (0x107) -#define CKA_SIGN (0x108) -#define CKA_SIGN_RECOVER (0x109) -#define CKA_VERIFY (0x10a) -#define CKA_VERIFY_RECOVER (0x10b) -#define CKA_DERIVE (0x10c) -#define CKA_START_DATE (0x110) -#define CKA_END_DATE (0x111) -#define CKA_MODULUS (0x120) -#define CKA_MODULUS_BITS (0x121) -#define CKA_PUBLIC_EXPONENT (0x122) -#define CKA_PRIVATE_EXPONENT (0x123) -#define CKA_PRIME_1 (0x124) -#define CKA_PRIME_2 (0x125) -#define CKA_EXPONENT_1 (0x126) -#define CKA_EXPONENT_2 (0x127) -#define CKA_COEFFICIENT (0x128) -#define CKA_PRIME (0x130) -#define CKA_SUBPRIME (0x131) -#define CKA_BASE (0x132) -#define CKA_PRIME_BITS (0x133) -#define CKA_SUB_PRIME_BITS (0x134) -#define CKA_VALUE_BITS (0x160) -#define CKA_VALUE_LEN (0x161) -#define CKA_EXTRACTABLE (0x162) -#define CKA_LOCAL (0x163) -#define CKA_NEVER_EXTRACTABLE (0x164) -#define CKA_ALWAYS_SENSITIVE (0x165) -#define CKA_KEY_GEN_MECHANISM (0x166) -#define CKA_MODIFIABLE (0x170) -#define CKA_ECDSA_PARAMS (0x180) -#define CKA_EC_PARAMS (0x180) -#define CKA_EC_POINT (0x181) -#define CKA_SECONDARY_AUTH (0x200) -#define CKA_AUTH_PIN_FLAGS (0x201) -#define CKA_ALWAYS_AUTHENTICATE (0x202) -#define CKA_WRAP_WITH_TRUSTED (0x210) -#define CKA_HW_FEATURE_TYPE (0x300) -#define CKA_RESET_ON_INIT (0x301) -#define CKA_HAS_RESET (0x302) -#define CKA_PIXEL_X (0x400) -#define CKA_PIXEL_Y (0x401) -#define CKA_RESOLUTION (0x402) -#define CKA_CHAR_ROWS (0x403) -#define CKA_CHAR_COLUMNS (0x404) -#define CKA_COLOR (0x405) -#define CKA_BITS_PER_PIXEL (0x406) -#define CKA_CHAR_SETS (0x480) -#define CKA_ENCODING_METHODS (0x481) -#define CKA_MIME_TYPES (0x482) -#define CKA_MECHANISM_TYPE (0x500) -#define CKA_REQUIRED_CMS_ATTRIBUTES (0x501) -#define CKA_DEFAULT_CMS_ATTRIBUTES (0x502) -#define CKA_SUPPORTED_CMS_ATTRIBUTES (0x503) -#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x211) -#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x212) -#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE | 0x600) -#define CKA_VENDOR_DEFINED (1U << 31) +#define CKA_CLASS (0UL) +#define CKA_TOKEN (1UL) +#define CKA_PRIVATE (2UL) +#define CKA_LABEL (3UL) +#define CKA_UNIQUE_ID (4UL) +#define CKA_APPLICATION (0x10UL) +#define CKA_VALUE (0x11UL) +#define CKA_OBJECT_ID (0x12UL) +#define CKA_CERTIFICATE_TYPE (0x80UL) +#define CKA_ISSUER (0x81UL) +#define CKA_SERIAL_NUMBER (0x82UL) +#define CKA_AC_ISSUER (0x83UL) +#define CKA_OWNER (0x84UL) +#define CKA_ATTR_TYPES (0x85UL) +#define CKA_TRUSTED (0x86UL) +#define CKA_CERTIFICATE_CATEGORY (0x87UL) +#define CKA_JAVA_MIDP_SECURITY_DOMAIN (0x88UL) +#define CKA_URL (0x89UL) +#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY (0x8aUL) +#define CKA_HASH_OF_ISSUER_PUBLIC_KEY (0x8bUL) +#define CKA_CHECK_VALUE (0x90UL) +#define CKA_KEY_TYPE (0x100UL) +#define CKA_SUBJECT (0x101UL) +#define CKA_ID (0x102UL) +#define CKA_SENSITIVE (0x103UL) +#define CKA_ENCRYPT (0x104UL) +#define CKA_DECRYPT (0x105UL) +#define CKA_WRAP (0x106UL) +#define CKA_UNWRAP (0x107UL) +#define CKA_SIGN (0x108UL) +#define CKA_SIGN_RECOVER (0x109UL) +#define CKA_VERIFY (0x10aUL) +#define CKA_VERIFY_RECOVER (0x10bUL) +#define CKA_DERIVE (0x10cUL) +#define CKA_START_DATE (0x110UL) +#define CKA_END_DATE (0x111UL) +#define CKA_MODULUS (0x120UL) +#define CKA_MODULUS_BITS (0x121UL) +#define CKA_PUBLIC_EXPONENT (0x122UL) +#define CKA_PRIVATE_EXPONENT (0x123UL) +#define CKA_PRIME_1 (0x124UL) +#define CKA_PRIME_2 (0x125UL) +#define CKA_EXPONENT_1 (0x126UL) +#define CKA_EXPONENT_2 (0x127UL) +#define CKA_COEFFICIENT (0x128UL) +#define CKA_PUBLIC_KEY_INFO (0x129UL) +#define CKA_PRIME (0x130UL) +#define CKA_SUBPRIME (0x131UL) +#define CKA_BASE (0x132UL) +#define CKA_PRIME_BITS (0x133UL) +#define CKA_SUB_PRIME_BITS (0x134UL) +#define CKA_VALUE_BITS (0x160UL) +#define CKA_VALUE_LEN (0x161UL) +#define CKA_EXTRACTABLE (0x162UL) +#define CKA_LOCAL (0x163UL) +#define CKA_NEVER_EXTRACTABLE (0x164UL) +#define CKA_ALWAYS_SENSITIVE (0x165UL) +#define CKA_KEY_GEN_MECHANISM (0x166UL) +#define CKA_MODIFIABLE (0x170UL) +#define CKA_COPYABLE (0x171UL) +#define CKA_DESTROYABLE (0x172UL) +#define CKA_ECDSA_PARAMS (0x180UL) +#define CKA_EC_PARAMS (0x180UL) +#define CKA_EC_POINT (0x181UL) +#define CKA_SECONDARY_AUTH (0x200UL) +#define CKA_AUTH_PIN_FLAGS (0x201UL) +#define CKA_ALWAYS_AUTHENTICATE (0x202UL) +#define CKA_WRAP_WITH_TRUSTED (0x210UL) +#define CKA_GOSTR3410_PARAMS (0x250UL) +#define CKA_GOSTR3411_PARAMS (0x251UL) +#define CKA_GOST28147_PARAMS (0x252UL) +#define CKA_HW_FEATURE_TYPE (0x300UL) +#define CKA_RESET_ON_INIT (0x301UL) +#define CKA_HAS_RESET (0x302UL) +#define CKA_PIXEL_X (0x400UL) +#define CKA_PIXEL_Y (0x401UL) +#define CKA_RESOLUTION (0x402UL) +#define CKA_CHAR_ROWS (0x403UL) +#define CKA_CHAR_COLUMNS (0x404UL) +#define CKA_COLOR (0x405UL) +#define CKA_BITS_PER_PIXEL (0x406UL) +#define CKA_CHAR_SETS (0x480UL) +#define CKA_ENCODING_METHODS (0x481UL) +#define CKA_MIME_TYPES (0x482UL) +#define CKA_MECHANISM_TYPE (0x500UL) +#define CKA_REQUIRED_CMS_ATTRIBUTES (0x501UL) +#define CKA_DEFAULT_CMS_ATTRIBUTES (0x502UL) +#define CKA_SUPPORTED_CMS_ATTRIBUTES (0x503UL) +#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x211UL) +#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x212UL) +#define CKA_OTP_FORMAT (0x220UL) +#define CKA_OTP_LENGTH (0x221UL) +#define CKA_OTP_TIME_INTERVAL (0x222UL) +#define CKA_OTP_USER_FRIENDLY_MODE (0x223UL) +#define CKA_OTP_CHALLENGE_REQUIREMENT (0x224UL) +#define CKA_OTP_TIME_REQUIREMENT (0x225UL) +#define CKA_OTP_COUNTER_REQUIREMENT (0x226UL) +#define CKA_OTP_PIN_REQUIREMENT (0x227UL) +#define CKA_OTP_USER_IDENTIFIER (0x22AUL) +#define CKA_OTP_SERVICE_IDENTIFIER (0x22BUL) +#define CKA_OTP_SERVICE_LOGO (0x22CUL) +#define CKA_OTP_SERVICE_LOGO_TYPE (0x22DUL) +#define CKA_OTP_COUNTER (0x22EUL) +#define CKA_OTP_TIME (0x22FUL) +#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE | 0x600UL) +#define CKA_PROFILE_ID (0x601UL) +#define CKA_VENDOR_DEFINED (1UL << 31) struct ck_attribute @@ -474,206 +522,304 @@ struct ck_date typedef unsigned long ck_mechanism_type_t; -#define CKM_RSA_PKCS_KEY_PAIR_GEN (0) -#define CKM_RSA_PKCS (1) -#define CKM_RSA_9796 (2) -#define CKM_RSA_X_509 (3) -#define CKM_MD2_RSA_PKCS (4) -#define CKM_MD5_RSA_PKCS (5) -#define CKM_SHA1_RSA_PKCS (6) -#define CKM_RIPEMD128_RSA_PKCS (7) -#define CKM_RIPEMD160_RSA_PKCS (8) -#define CKM_RSA_PKCS_OAEP (9) -#define CKM_RSA_X9_31_KEY_PAIR_GEN (0xa) -#define CKM_RSA_X9_31 (0xb) -#define CKM_SHA1_RSA_X9_31 (0xc) -#define CKM_RSA_PKCS_PSS (0xd) -#define CKM_SHA1_RSA_PKCS_PSS (0xe) -#define CKM_DSA_KEY_PAIR_GEN (0x10) -#define CKM_DSA (0x11) -#define CKM_DSA_SHA1 (0x12) -#define CKM_DH_PKCS_KEY_PAIR_GEN (0x20) -#define CKM_DH_PKCS_DERIVE (0x21) -#define CKM_X9_42_DH_KEY_PAIR_GEN (0x30) -#define CKM_X9_42_DH_DERIVE (0x31) -#define CKM_X9_42_DH_HYBRID_DERIVE (0x32) -#define CKM_X9_42_MQV_DERIVE (0x33) -#define CKM_SHA256_RSA_PKCS (0x40) -#define CKM_SHA384_RSA_PKCS (0x41) -#define CKM_SHA512_RSA_PKCS (0x42) -#define CKM_SHA256_RSA_PKCS_PSS (0x43) -#define CKM_SHA384_RSA_PKCS_PSS (0x44) -#define CKM_SHA512_RSA_PKCS_PSS (0x45) -#define CKM_RC2_KEY_GEN (0x100) -#define CKM_RC2_ECB (0x101) -#define CKM_RC2_CBC (0x102) -#define CKM_RC2_MAC (0x103) -#define CKM_RC2_MAC_GENERAL (0x104) -#define CKM_RC2_CBC_PAD (0x105) -#define CKM_RC4_KEY_GEN (0x110) -#define CKM_RC4 (0x111) -#define CKM_DES_KEY_GEN (0x120) -#define CKM_DES_ECB (0x121) -#define CKM_DES_CBC (0x122) -#define CKM_DES_MAC (0x123) -#define CKM_DES_MAC_GENERAL (0x124) -#define CKM_DES_CBC_PAD (0x125) -#define CKM_DES2_KEY_GEN (0x130) -#define CKM_DES3_KEY_GEN (0x131) -#define CKM_DES3_ECB (0x132) -#define CKM_DES3_CBC (0x133) -#define CKM_DES3_MAC (0x134) -#define CKM_DES3_MAC_GENERAL (0x135) -#define CKM_DES3_CBC_PAD (0x136) -#define CKM_CDMF_KEY_GEN (0x140) -#define CKM_CDMF_ECB (0x141) -#define CKM_CDMF_CBC (0x142) -#define CKM_CDMF_MAC (0x143) -#define CKM_CDMF_MAC_GENERAL (0x144) -#define CKM_CDMF_CBC_PAD (0x145) -#define CKM_MD2 (0x200) -#define CKM_MD2_HMAC (0x201) -#define CKM_MD2_HMAC_GENERAL (0x202) -#define CKM_MD5 (0x210) -#define CKM_MD5_HMAC (0x211) -#define CKM_MD5_HMAC_GENERAL (0x212) -#define CKM_SHA_1 (0x220) -#define CKM_SHA_1_HMAC (0x221) -#define CKM_SHA_1_HMAC_GENERAL (0x222) -#define CKM_RIPEMD128 (0x230) -#define CKM_RIPEMD128_HMAC (0x231) -#define CKM_RIPEMD128_HMAC_GENERAL (0x232) -#define CKM_RIPEMD160 (0x240) -#define CKM_RIPEMD160_HMAC (0x241) -#define CKM_RIPEMD160_HMAC_GENERAL (0x242) -#define CKM_SHA256 (0x250) -#define CKM_SHA256_HMAC (0x251) -#define CKM_SHA256_HMAC_GENERAL (0x252) -#define CKM_SHA384 (0x260) -#define CKM_SHA384_HMAC (0x261) -#define CKM_SHA384_HMAC_GENERAL (0x262) -#define CKM_SHA512 (0x270) -#define CKM_SHA512_HMAC (0x271) -#define CKM_SHA512_HMAC_GENERAL (0x272) -#define CKM_CAST_KEY_GEN (0x300) -#define CKM_CAST_ECB (0x301) -#define CKM_CAST_CBC (0x302) -#define CKM_CAST_MAC (0x303) -#define CKM_CAST_MAC_GENERAL (0x304) -#define CKM_CAST_CBC_PAD (0x305) -#define CKM_CAST3_KEY_GEN (0x310) -#define CKM_CAST3_ECB (0x311) -#define CKM_CAST3_CBC (0x312) -#define CKM_CAST3_MAC (0x313) -#define CKM_CAST3_MAC_GENERAL (0x314) -#define CKM_CAST3_CBC_PAD (0x315) -#define CKM_CAST5_KEY_GEN (0x320) -#define CKM_CAST128_KEY_GEN (0x320) -#define CKM_CAST5_ECB (0x321) -#define CKM_CAST128_ECB (0x321) -#define CKM_CAST5_CBC (0x322) -#define CKM_CAST128_CBC (0x322) -#define CKM_CAST5_MAC (0x323) -#define CKM_CAST128_MAC (0x323) -#define CKM_CAST5_MAC_GENERAL (0x324) -#define CKM_CAST128_MAC_GENERAL (0x324) -#define CKM_CAST5_CBC_PAD (0x325) -#define CKM_CAST128_CBC_PAD (0x325) -#define CKM_RC5_KEY_GEN (0x330) -#define CKM_RC5_ECB (0x331) -#define CKM_RC5_CBC (0x332) -#define CKM_RC5_MAC (0x333) -#define CKM_RC5_MAC_GENERAL (0x334) -#define CKM_RC5_CBC_PAD (0x335) -#define CKM_IDEA_KEY_GEN (0x340) -#define CKM_IDEA_ECB (0x341) -#define CKM_IDEA_CBC (0x342) -#define CKM_IDEA_MAC (0x343) -#define CKM_IDEA_MAC_GENERAL (0x344) -#define CKM_IDEA_CBC_PAD (0x345) -#define CKM_GENERIC_SECRET_KEY_GEN (0x350) -#define CKM_CONCATENATE_BASE_AND_KEY (0x360) -#define CKM_CONCATENATE_BASE_AND_DATA (0x362) -#define CKM_CONCATENATE_DATA_AND_BASE (0x363) -#define CKM_XOR_BASE_AND_DATA (0x364) -#define CKM_EXTRACT_KEY_FROM_KEY (0x365) -#define CKM_SSL3_PRE_MASTER_KEY_GEN (0x370) -#define CKM_SSL3_MASTER_KEY_DERIVE (0x371) -#define CKM_SSL3_KEY_AND_MAC_DERIVE (0x372) -#define CKM_SSL3_MASTER_KEY_DERIVE_DH (0x373) -#define CKM_TLS_PRE_MASTER_KEY_GEN (0x374) -#define CKM_TLS_MASTER_KEY_DERIVE (0x375) -#define CKM_TLS_KEY_AND_MAC_DERIVE (0x376) -#define CKM_TLS_MASTER_KEY_DERIVE_DH (0x377) -#define CKM_SSL3_MD5_MAC (0x380) -#define CKM_SSL3_SHA1_MAC (0x381) -#define CKM_MD5_KEY_DERIVATION (0x390) -#define CKM_MD2_KEY_DERIVATION (0x391) -#define CKM_SHA1_KEY_DERIVATION (0x392) -#define CKM_PBE_MD2_DES_CBC (0x3a0) -#define CKM_PBE_MD5_DES_CBC (0x3a1) -#define CKM_PBE_MD5_CAST_CBC (0x3a2) -#define CKM_PBE_MD5_CAST3_CBC (0x3a3) -#define CKM_PBE_MD5_CAST5_CBC (0x3a4) -#define CKM_PBE_MD5_CAST128_CBC (0x3a4) -#define CKM_PBE_SHA1_CAST5_CBC (0x3a5) -#define CKM_PBE_SHA1_CAST128_CBC (0x3a5) -#define CKM_PBE_SHA1_RC4_128 (0x3a6) -#define CKM_PBE_SHA1_RC4_40 (0x3a7) -#define CKM_PBE_SHA1_DES3_EDE_CBC (0x3a8) -#define CKM_PBE_SHA1_DES2_EDE_CBC (0x3a9) -#define CKM_PBE_SHA1_RC2_128_CBC (0x3aa) -#define CKM_PBE_SHA1_RC2_40_CBC (0x3ab) -#define CKM_PKCS5_PBKD2 (0x3b0) -#define CKM_PBA_SHA1_WITH_SHA1_HMAC (0x3c0) -#define CKM_KEY_WRAP_LYNKS (0x400) -#define CKM_KEY_WRAP_SET_OAEP (0x401) -#define CKM_SKIPJACK_KEY_GEN (0x1000) -#define CKM_SKIPJACK_ECB64 (0x1001) -#define CKM_SKIPJACK_CBC64 (0x1002) -#define CKM_SKIPJACK_OFB64 (0x1003) -#define CKM_SKIPJACK_CFB64 (0x1004) -#define CKM_SKIPJACK_CFB32 (0x1005) -#define CKM_SKIPJACK_CFB16 (0x1006) -#define CKM_SKIPJACK_CFB8 (0x1007) -#define CKM_SKIPJACK_WRAP (0x1008) -#define CKM_SKIPJACK_PRIVATE_WRAP (0x1009) -#define CKM_SKIPJACK_RELAYX (0x100a) -#define CKM_KEA_KEY_PAIR_GEN (0x1010) -#define CKM_KEA_KEY_DERIVE (0x1011) -#define CKM_FORTEZZA_TIMESTAMP (0x1020) -#define CKM_BATON_KEY_GEN (0x1030) -#define CKM_BATON_ECB128 (0x1031) -#define CKM_BATON_ECB96 (0x1032) -#define CKM_BATON_CBC128 (0x1033) -#define CKM_BATON_COUNTER (0x1034) -#define CKM_BATON_SHUFFLE (0x1035) -#define CKM_BATON_WRAP (0x1036) -#define CKM_ECDSA_KEY_PAIR_GEN (0x1040) -#define CKM_EC_KEY_PAIR_GEN (0x1040) -#define CKM_ECDSA (0x1041) -#define CKM_ECDSA_SHA1 (0x1042) -#define CKM_ECDH1_DERIVE (0x1050) -#define CKM_ECDH1_COFACTOR_DERIVE (0x1051) -#define CKM_ECMQV_DERIVE (0x1052) -#define CKM_JUNIPER_KEY_GEN (0x1060) -#define CKM_JUNIPER_ECB128 (0x1061) -#define CKM_JUNIPER_CBC128 (0x1062) -#define CKM_JUNIPER_COUNTER (0x1063) -#define CKM_JUNIPER_SHUFFLE (0x1064) -#define CKM_JUNIPER_WRAP (0x1065) -#define CKM_FASTHASH (0x1070) -#define CKM_AES_KEY_GEN (0x1080) -#define CKM_AES_ECB (0x1081) -#define CKM_AES_CBC (0x1082) -#define CKM_AES_MAC (0x1083) -#define CKM_AES_MAC_GENERAL (0x1084) -#define CKM_AES_CBC_PAD (0x1085) -#define CKM_DSA_PARAMETER_GEN (0x2000) -#define CKM_DH_PKCS_PARAMETER_GEN (0x2001) -#define CKM_X9_42_DH_PARAMETER_GEN (0x2002) -#define CKM_VENDOR_DEFINED (1U << 31) - +#define CKM_RSA_PKCS_KEY_PAIR_GEN (0UL) +#define CKM_RSA_PKCS (1UL) +#define CKM_RSA_9796 (2UL) +#define CKM_RSA_X_509 (3UL) +#define CKM_MD2_RSA_PKCS (4UL) +#define CKM_MD5_RSA_PKCS (5UL) +#define CKM_SHA1_RSA_PKCS (6UL) +#define CKM_RIPEMD128_RSA_PKCS (7UL) +#define CKM_RIPEMD160_RSA_PKCS (8UL) +#define CKM_RSA_PKCS_OAEP (9UL) +#define CKM_RSA_X9_31_KEY_PAIR_GEN (0xaUL) +#define CKM_RSA_X9_31 (0xbUL) +#define CKM_SHA1_RSA_X9_31 (0xcUL) +#define CKM_RSA_PKCS_PSS (0xdUL) +#define CKM_SHA1_RSA_PKCS_PSS (0xeUL) +#define CKM_DSA_KEY_PAIR_GEN (0x10UL) +#define CKM_DSA (0x11UL) +#define CKM_DSA_SHA1 (0x12UL) +#define CKM_DSA_SHA224 (0x13UL) +#define CKM_DSA_SHA256 (0x14UL) +#define CKM_DSA_SHA384 (0x15UL) +#define CKM_DSA_SHA512 (0x16UL) +#define CKM_DH_PKCS_KEY_PAIR_GEN (0x20UL) +#define CKM_DH_PKCS_DERIVE (0x21UL) +#define CKM_X9_42_DH_KEY_PAIR_GEN (0x30UL) +#define CKM_X9_42_DH_DERIVE (0x31UL) +#define CKM_X9_42_DH_HYBRID_DERIVE (0x32UL) +#define CKM_X9_42_MQV_DERIVE (0x33UL) +#define CKM_SHA256_RSA_PKCS (0x40UL) +#define CKM_SHA384_RSA_PKCS (0x41UL) +#define CKM_SHA512_RSA_PKCS (0x42UL) +#define CKM_SHA256_RSA_PKCS_PSS (0x43UL) +#define CKM_SHA384_RSA_PKCS_PSS (0x44UL) +#define CKM_SHA512_RSA_PKCS_PSS (0x45UL) +#define CKM_SHA224_RSA_PKCS (0x46UL) +#define CKM_SHA224_RSA_PKCS_PSS (0x47UL) +#define CKM_SHA3_256_RSA_PKCS (0x60UL) +#define CKM_SHA3_384_RSA_PKCS (0x61UL) +#define CKM_SHA3_512_RSA_PKCS (0x62UL) +#define CKM_SHA3_256_RSA_PKCS_PSS (0x63UL) +#define CKM_SHA3_384_RSA_PKCS_PSS (0x64UL) +#define CKM_SHA3_512_RSA_PKCS_PSS (0x65UL) +#define CKM_SHA3_224_RSA_PKCS (0x66UL) +#define CKM_SHA3_224_RSA_PKCS_PSS (0x67UL) +#define CKM_RC2_KEY_GEN (0x100UL) +#define CKM_RC2_ECB (0x101UL) +#define CKM_RC2_CBC (0x102UL) +#define CKM_RC2_MAC (0x103UL) +#define CKM_RC2_MAC_GENERAL (0x104UL) +#define CKM_RC2_CBC_PAD (0x105UL) +#define CKM_RC4_KEY_GEN (0x110UL) +#define CKM_RC4 (0x111UL) +#define CKM_DES_KEY_GEN (0x120UL) +#define CKM_DES_ECB (0x121UL) +#define CKM_DES_CBC (0x122UL) +#define CKM_DES_MAC (0x123UL) +#define CKM_DES_MAC_GENERAL (0x124UL) +#define CKM_DES_CBC_PAD (0x125UL) +#define CKM_DES2_KEY_GEN (0x130UL) +#define CKM_DES3_KEY_GEN (0x131UL) +#define CKM_DES3_ECB (0x132UL) +#define CKM_DES3_CBC (0x133UL) +#define CKM_DES3_MAC (0x134UL) +#define CKM_DES3_MAC_GENERAL (0x135UL) +#define CKM_DES3_CBC_PAD (0x136UL) +#define CKM_DES3_CMAC_GENERAL (0x137UL) +#define CKM_DES3_CMAC (0x138UL) +#define CKM_CDMF_KEY_GEN (0x140UL) +#define CKM_CDMF_ECB (0x141UL) +#define CKM_CDMF_CBC (0x142UL) +#define CKM_CDMF_MAC (0x143UL) +#define CKM_CDMF_MAC_GENERAL (0x144UL) +#define CKM_CDMF_CBC_PAD (0x145UL) +#define CKM_MD2 (0x200UL) +#define CKM_MD2_HMAC (0x201UL) +#define CKM_MD2_HMAC_GENERAL (0x202UL) +#define CKM_MD5 (0x210UL) +#define CKM_MD5_HMAC (0x211UL) +#define CKM_MD5_HMAC_GENERAL (0x212UL) +#define CKM_SHA_1 (0x220UL) +#define CKM_SHA_1_HMAC (0x221UL) +#define CKM_SHA_1_HMAC_GENERAL (0x222UL) +#define CKM_RIPEMD128 (0x230UL) +#define CKM_RIPEMD128_HMAC (0x231UL) +#define CKM_RIPEMD128_HMAC_GENERAL (0x232UL) +#define CKM_RIPEMD160 (0x240UL) +#define CKM_RIPEMD160_HMAC (0x241UL) +#define CKM_RIPEMD160_HMAC_GENERAL (0x242UL) +#define CKM_SHA256 (0x250UL) +#define CKM_SHA256_HMAC (0x251UL) +#define CKM_SHA256_HMAC_GENERAL (0x252UL) +#define CKM_SHA224 (0x255UL) +#define CKM_SHA224_HMAC (0x256UL) +#define CKM_SHA224_HMAC_GENERAL (0x257UL) +#define CKM_SHA384 (0x260UL) +#define CKM_SHA384_HMAC (0x261UL) +#define CKM_SHA384_HMAC_GENERAL (0x262UL) +#define CKM_SHA512 (0x270UL) +#define CKM_SHA512_HMAC (0x271UL) +#define CKM_SHA512_HMAC_GENERAL (0x272UL) +#define CKM_SHA3_256 (0x2B0UL) +#define CKM_SHA3_256_HMAC (0x2B1UL) +#define CKM_SHA3_256_HMAC_GENERAL (0x2B2UL) +#define CKM_SHA3_256_KEY_GEN (0x2B3UL) +#define CKM_SHA3_224 (0x2B5UL) +#define CKM_SHA3_224_HMAC (0x2B6UL) +#define CKM_SHA3_224_HMAC_GENERAL (0x2B7UL) +#define CKM_SHA3_224_KEY_GEN (0x2B8UL) +#define CKM_SHA3_384 (0x2C0UL) +#define CKM_SHA3_384_HMAC (0x2C1UL) +#define CKM_SHA3_384_HMAC_GENERAL (0x2C2UL) +#define CKM_SHA3_384_KEY_GEN (0x2C3UL) +#define CKM_SHA3_512 (0x2D0UL) +#define CKM_SHA3_512_HMAC (0x2D1UL) +#define CKM_SHA3_512_HMAC_GENERAL (0x2D2UL) +#define CKM_SHA3_512_KEY_GEN (0x2D3UL) +#define CKM_CAST_KEY_GEN (0x300UL) +#define CKM_CAST_ECB (0x301UL) +#define CKM_CAST_CBC (0x302UL) +#define CKM_CAST_MAC (0x303UL) +#define CKM_CAST_MAC_GENERAL (0x304UL) +#define CKM_CAST_CBC_PAD (0x305UL) +#define CKM_CAST3_KEY_GEN (0x310UL) +#define CKM_CAST3_ECB (0x311UL) +#define CKM_CAST3_CBC (0x312UL) +#define CKM_CAST3_MAC (0x313UL) +#define CKM_CAST3_MAC_GENERAL (0x314UL) +#define CKM_CAST3_CBC_PAD (0x315UL) +#define CKM_CAST5_KEY_GEN (0x320UL) +#define CKM_CAST128_KEY_GEN (0x320UL) +#define CKM_CAST5_ECB (0x321UL) +#define CKM_CAST128_ECB (0x321UL) +#define CKM_CAST5_CBC (0x322UL) +#define CKM_CAST128_CBC (0x322UL) +#define CKM_CAST5_MAC (0x323UL) +#define CKM_CAST128_MAC (0x323UL) +#define CKM_CAST5_MAC_GENERAL (0x324UL) +#define CKM_CAST128_MAC_GENERAL (0x324UL) +#define CKM_CAST5_CBC_PAD (0x325UL) +#define CKM_CAST128_CBC_PAD (0x325UL) +#define CKM_RC5_KEY_GEN (0x330UL) +#define CKM_RC5_ECB (0x331UL) +#define CKM_RC5_CBC (0x332UL) +#define CKM_RC5_MAC (0x333UL) +#define CKM_RC5_MAC_GENERAL (0x334UL) +#define CKM_RC5_CBC_PAD (0x335UL) +#define CKM_IDEA_KEY_GEN (0x340UL) +#define CKM_IDEA_ECB (0x341UL) +#define CKM_IDEA_CBC (0x342UL) +#define CKM_IDEA_MAC (0x343UL) +#define CKM_IDEA_MAC_GENERAL (0x344UL) +#define CKM_IDEA_CBC_PAD (0x345UL) +#define CKM_GENERIC_SECRET_KEY_GEN (0x350UL) +#define CKM_CONCATENATE_BASE_AND_KEY (0x360UL) +#define CKM_CONCATENATE_BASE_AND_DATA (0x362UL) +#define CKM_CONCATENATE_DATA_AND_BASE (0x363UL) +#define CKM_XOR_BASE_AND_DATA (0x364UL) +#define CKM_EXTRACT_KEY_FROM_KEY (0x365UL) +#define CKM_SSL3_PRE_MASTER_KEY_GEN (0x370UL) +#define CKM_SSL3_MASTER_KEY_DERIVE (0x371UL) +#define CKM_SSL3_KEY_AND_MAC_DERIVE (0x372UL) +#define CKM_SSL3_MASTER_KEY_DERIVE_DH (0x373UL) +#define CKM_TLS_PRE_MASTER_KEY_GEN (0x374UL) +#define CKM_TLS_MASTER_KEY_DERIVE (0x375UL) +#define CKM_TLS_KEY_AND_MAC_DERIVE (0x376UL) +#define CKM_TLS_MASTER_KEY_DERIVE_DH (0x377UL) +#define CKM_SSL3_MD5_MAC (0x380UL) +#define CKM_SSL3_SHA1_MAC (0x381UL) +#define CKM_MD5_KEY_DERIVATION (0x390UL) +#define CKM_MD2_KEY_DERIVATION (0x391UL) +#define CKM_SHA1_KEY_DERIVATION (0x392UL) +#define CKM_PBE_MD2_DES_CBC (0x3a0UL) +#define CKM_PBE_MD5_DES_CBC (0x3a1UL) +#define CKM_PBE_MD5_CAST_CBC (0x3a2UL) +#define CKM_PBE_MD5_CAST3_CBC (0x3a3UL) +#define CKM_PBE_MD5_CAST5_CBC (0x3a4UL) +#define CKM_PBE_MD5_CAST128_CBC (0x3a4UL) +#define CKM_PBE_SHA1_CAST5_CBC (0x3a5UL) +#define CKM_PBE_SHA1_CAST128_CBC (0x3a5UL) +#define CKM_PBE_SHA1_RC4_128 (0x3a6UL) +#define CKM_PBE_SHA1_RC4_40 (0x3a7UL) +#define CKM_PBE_SHA1_DES3_EDE_CBC (0x3a8UL) +#define CKM_PBE_SHA1_DES2_EDE_CBC (0x3a9UL) +#define CKM_PBE_SHA1_RC2_128_CBC (0x3aaUL) +#define CKM_PBE_SHA1_RC2_40_CBC (0x3abUL) +#define CKM_PKCS5_PBKD2 (0x3b0UL) +#define CKM_PBA_SHA1_WITH_SHA1_HMAC (0x3c0UL) +#define CKM_KEY_WRAP_LYNKS (0x400UL) +#define CKM_KEY_WRAP_SET_OAEP (0x401UL) +#define CKM_SKIPJACK_KEY_GEN (0x1000UL) +#define CKM_SKIPJACK_ECB64 (0x1001UL) +#define CKM_SKIPJACK_CBC64 (0x1002UL) +#define CKM_SKIPJACK_OFB64 (0x1003UL) +#define CKM_SKIPJACK_CFB64 (0x1004UL) +#define CKM_SKIPJACK_CFB32 (0x1005UL) +#define CKM_SKIPJACK_CFB16 (0x1006UL) +#define CKM_SKIPJACK_CFB8 (0x1007UL) +#define CKM_SKIPJACK_WRAP (0x1008UL) +#define CKM_SKIPJACK_PRIVATE_WRAP (0x1009UL) +#define CKM_SKIPJACK_RELAYX (0x100aUL) +#define CKM_KEA_KEY_PAIR_GEN (0x1010UL) +#define CKM_KEA_KEY_DERIVE (0x1011UL) +#define CKM_FORTEZZA_TIMESTAMP (0x1020UL) +#define CKM_BATON_KEY_GEN (0x1030UL) +#define CKM_BATON_ECB128 (0x1031UL) +#define CKM_BATON_ECB96 (0x1032UL) +#define CKM_BATON_CBC128 (0x1033UL) +#define CKM_BATON_COUNTER (0x1034UL) +#define CKM_BATON_SHUFFLE (0x1035UL) +#define CKM_BATON_WRAP (0x1036UL) +#define CKM_ECDSA_KEY_PAIR_GEN (0x1040UL) +#define CKM_EC_KEY_PAIR_GEN (0x1040UL) +#define CKM_ECDSA (0x1041UL) +#define CKM_ECDSA_SHA1 (0x1042UL) +#define CKM_ECDSA_SHA224 (0x1043UL) +#define CKM_ECDSA_SHA256 (0x1044UL) +#define CKM_ECDSA_SHA384 (0x1045UL) +#define CKM_ECDSA_SHA512 (0x1046UL) +#define CKM_ECDSA_SHA3_224 (0x1047UL) +#define CKM_ECDSA_SHA3_256 (0x1048UL) +#define CKM_ECDSA_SHA3_384 (0x1049UL) +#define CKM_ECDSA_SHA3_512 (0x104AUL) +#define CKM_ECDH1_DERIVE (0x1050UL) +#define CKM_ECDH1_COFACTOR_DERIVE (0x1051UL) +#define CKM_ECMQV_DERIVE (0x1052UL) +#define CKM_EC_EDWARDS_KEY_PAIR_GEN (0x1055UL) +#define CKM_EC_MONTGOMERY_KEY_PAIR_GEN (0x1056UL) +#define CKM_EDDSA (0x1057UL) +#define CKM_JUNIPER_KEY_GEN (0x1060UL) +#define CKM_JUNIPER_ECB128 (0x1061UL) +#define CKM_JUNIPER_CBC128 (0x1062UL) +#define CKM_JUNIPER_COUNTER (0x1063UL) +#define CKM_JUNIPER_SHUFFLE (0x1064UL) +#define CKM_JUNIPER_WRAP (0x1065UL) +#define CKM_FASTHASH (0x1070UL) +#define CKM_AES_KEY_GEN (0x1080UL) +#define CKM_AES_ECB (0x1081UL) +#define CKM_AES_CBC (0x1082UL) +#define CKM_AES_MAC (0x1083UL) +#define CKM_AES_MAC_GENERAL (0x1084UL) +#define CKM_AES_CBC_PAD (0x1085UL) +#define CKM_AES_CTR (0x1086UL) +#define CKM_AES_GCM (0x1087UL) +#define CKM_AES_CCM (0x1088UL) +#define CKM_AES_CTS (0x1089UL) +#define CKM_AES_CMAC (0x108AUL) +#define CKM_AES_CMAC_GENERAL (0x108BUL) +#define CKM_AES_XCBC_MAC (0x108CUL) +#define CKM_AES_XCBC_MAC_96 (0x108DUL) +#define CKM_AES_GMAC (0x108EUL) +#define CKM_BLOWFISH_KEY_GEN (0x1090UL) +#define CKM_BLOWFISH_CBC (0x1091UL) +#define CKM_TWOFISH_KEY_GEN (0x1092UL) +#define CKM_TWOFISH_CBC (0x1093UL) +#define CKM_DES_ECB_ENCRYPT_DATA (0x1100UL) +#define CKM_DES_CBC_ENCRYPT_DATA (0x1101UL) +#define CKM_DES3_ECB_ENCRYPT_DATA (0x1102UL) +#define CKM_DES3_CBC_ENCRYPT_DATA (0x1103UL) +#define CKM_AES_ECB_ENCRYPT_DATA (0x1104UL) +#define CKM_AES_CBC_ENCRYPT_DATA (0x1105UL) +#define CKM_GOSTR3410_KEY_PAIR_GEN (0x1200UL) +#define CKM_GOSTR3410 (0x1201UL) +#define CKM_GOSTR3410_WITH_GOSTR3411 (0x1202UL) +#define CKM_GOSTR3410_KEY_WRAP (0x1203UL) +#define CKM_GOSTR3410_DERIVE (0x1204UL) +#define CKM_GOSTR3410_512_KEY_PAIR_GEN (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x005) +#define CKM_GOSTR3410_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x006) +#define CKM_GOSTR3410_12_DERIVE (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x007) +#define CKM_GOSTR3410_WITH_GOSTR3411_12_256 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x008) +#define CKM_GOSTR3410_WITH_GOSTR3411_12_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x009) +#define CKM_GOSTR3411 (0x1210UL) +#define CKM_GOSTR3411_HMAC (0x1211UL) +#define CKM_GOSTR3411_12_256 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x012) +#define CKM_GOSTR3411_12_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x013) +#define CKM_GOSTR3411_12_256_HMAC (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x014) +#define CKM_GOSTR3411_12_512_HMAC (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x015) +#define CKM_GOST28147_KEY_GEN (0x1220UL) +#define CKM_GOST28147_ECB (0x1221UL) +#define CKM_GOST28147 (0x1222UL) +#define CKM_GOST28147_MAC (0x1223UL) +#define CKM_GOST28147_KEY_WRAP (0x1224UL) + +#define CKM_DSA_PARAMETER_GEN (0x2000UL) +#define CKM_DH_PKCS_PARAMETER_GEN (0x2001UL) +#define CKM_X9_42_DH_PARAMETER_GEN (0x2002UL) +#define CKM_AES_OFB (0x2104UL) +#define CKM_AES_CFB64 (0x2105UL) +#define CKM_AES_CFB8 (0x2106UL) +#define CKM_AES_CFB128 (0x2107UL) +#define CKM_AES_CFB1 (0x2108UL) +#define CKM_AES_KEY_WRAP (0x2109UL) +#define CKM_AES_KEY_WRAP_PAD (0x210AUL) +#define CKM_XEDDSA (0x4029UL) +#define CKM_HKDF_DERIVE (0x402AUL) +#define CKM_HKDF_DATA (0x402BUL) +#define CKM_HKDF_KEY_GEN (0x402CUL) + +#define CKM_VENDOR_DEFINED (1UL << 31) struct ck_mechanism { @@ -690,25 +836,143 @@ struct ck_mechanism_info ck_flags_t flags; }; -#define CKF_HW (1 << 0) -#define CKF_ENCRYPT (1 << 8) -#define CKF_DECRYPT (1 << 9) -#define CKF_DIGEST (1 << 10) -#define CKF_SIGN (1 << 11) -#define CKF_SIGN_RECOVER (1 << 12) -#define CKF_VERIFY (1 << 13) -#define CKF_VERIFY_RECOVER (1 << 14) -#define CKF_GENERATE (1 << 15) -#define CKF_GENERATE_KEY_PAIR (1 << 16) -#define CKF_WRAP (1 << 17) -#define CKF_UNWRAP (1 << 18) -#define CKF_DERIVE (1 << 19) -#define CKF_EXTENSION (1U << 31) - +#define CKF_HW (1UL << 0) + +#define CKF_MESSAGE_ENCRYPT (1UL << 1) +#define CKF_MESSAGE_DECRYPT (1UL << 2) +#define CKF_MESSAGE_SIGN (1UL << 3) +#define CKF_MESSAGE_VERIFY (1UL << 4) +#define CKF_MULTI_MESSAGE (1UL << 5) +#define CKF_FIND_OBJECTS (1UL << 6) + +#define CKF_ENCRYPT (1UL << 8) +#define CKF_DECRYPT (1UL << 9) +#define CKF_DIGEST (1UL << 10) +#define CKF_SIGN (1UL << 11) +#define CKF_SIGN_RECOVER (1UL << 12) +#define CKF_VERIFY (1UL << 13) +#define CKF_VERIFY_RECOVER (1UL << 14) +#define CKF_GENERATE (1UL << 15) +#define CKF_GENERATE_KEY_PAIR (1UL << 16) +#define CKF_WRAP (1UL << 17) +#define CKF_UNWRAP (1UL << 18) +#define CKF_DERIVE (1UL << 19) +#define CKF_EXTENSION (1UL << 31) + +#define CKF_EC_F_P (1UL << 20) +#define CKF_EC_F_2M (1UL << 21) +#define CKF_EC_ECPARAMETERS (1UL << 22) +#define CKF_EC_OID (1UL << 23) +#define CKF_EC_NAMEDCURVE CKF_EC_OID +#define CKF_EC_UNCOMPRESS (1UL << 24) +#define CKF_EC_COMPRESS (1UL << 25) +#define CKF_EC_CURVENAME (1UL << 26) /* Flags for C_WaitForSlotEvent. */ -#define CKF_DONT_BLOCK (1) - +#define CKF_DONT_BLOCK (1UL) + +/* Flags for Key derivation */ +#define CKD_NULL (0x1UL) +#define CKD_SHA1_KDF (0x2UL) +#define CKD_SHA224_KDF (0x5UL) +#define CKD_SHA256_KDF (0x6UL) +#define CKD_SHA384_KDF (0x7UL) +#define CKD_SHA512_KDF (0x8UL) + +typedef struct CK_ECDH1_DERIVE_PARAMS { + unsigned long kdf; + unsigned long ulSharedDataLen; + unsigned char * pSharedData; + unsigned long ulPublicDataLen; + unsigned char * pPublicData; +} CK_ECDH1_DERIVE_PARAMS; + +typedef struct CK_ECMQV_DERIVE_PARAMS { + unsigned long kdf; + unsigned long ulSharedDataLen; + unsigned char * pSharedData; + unsigned long ulPublicDataLen; + unsigned char * pPublicData; + unsigned long ulPrivateDataLen; + CK_OBJECT_HANDLE hPrivateData; + unsigned long ulPublicDataLen2; + unsigned char * pPublicData2; + CK_OBJECT_HANDLE publicKey; +} CK_ECMQV_DERIVE_PARAMS; + +typedef unsigned long ck_rsa_pkcs_mgf_type_t; +typedef unsigned long CK_RSA_PKCS_OAEP_SOURCE_TYPE; + +typedef struct CK_RSA_PKCS_OAEP_PARAMS { + CK_MECHANISM_TYPE hashAlg; + CK_RSA_PKCS_MGF_TYPE mgf; + CK_RSA_PKCS_OAEP_SOURCE_TYPE source; + void *pSourceData; + unsigned long ulSourceDataLen; +} CK_RSA_PKCS_OAEP_PARAMS; + +typedef struct CK_RSA_PKCS_PSS_PARAMS { + ck_mechanism_type_t hashAlg; + CK_RSA_PKCS_MGF_TYPE mgf; + unsigned long sLen; +} CK_RSA_PKCS_PSS_PARAMS; + +#define CKG_MGF1_SHA1 (0x00000001UL) +#define CKG_MGF1_SHA224 (0x00000005UL) +#define CKG_MGF1_SHA256 (0x00000002UL) +#define CKG_MGF1_SHA384 (0x00000003UL) +#define CKG_MGF1_SHA512 (0x00000004UL) +#define CKG_MGF1_SHA3_224 (0x00000006UL) +#define CKG_MGF1_SHA3_256 (0x00000007UL) +#define CKG_MGF1_SHA3_384 (0x00000008UL) +#define CKG_MGF1_SHA3_512 (0x00000009UL) + +#define CKZ_DATA_SPECIFIED (0x00000001UL) + +typedef struct CK_GCM_PARAMS { + void * pIv; + unsigned long ulIvLen; + unsigned long ulIvBits; + void * pAAD; + unsigned long ulAADLen; + unsigned long ulTagBits; +} CK_GCM_PARAMS; + +typedef struct CK_CCM_PARAMS { + unsigned long ulDataLen; + unsigned char *pNonce; + unsigned long ulNonceLen; + unsigned char *pAAD; + unsigned long ulAADLen; + unsigned long ulMACLen; +} CK_CCM_PARAMS; + +/* EDDSA */ +typedef struct CK_EDDSA_PARAMS { + unsigned char phFlag; + unsigned long ulContextDataLen; + unsigned char *pContextData; +} CK_EDDSA_PARAMS; + +typedef CK_EDDSA_PARAMS *CK_EDDSA_PARAMS_PTR; + +/* XEDDSA */ +typedef struct CK_XEDDSA_PARAMS { + unsigned long hash; +} CK_XEDDSA_PARAMS; + +typedef CK_XEDDSA_PARAMS *CK_XEDDSA_PARAMS_PTR; + +typedef struct CK_AES_CTR_PARAMS { + unsigned long ulCounterBits; + unsigned char cb[16]; +} CK_AES_CTR_PARAMS; + +typedef CK_AES_CTR_PARAMS *CK_AES_CTR_PARAMS_PTR; + +typedef unsigned long CK_MAC_GENERAL_PARAMS; + +typedef CK_MAC_GENERAL_PARAMS *CK_MAC_GENERAL_PARAMS_PTR; typedef unsigned long ck_rv_t; @@ -716,8 +980,17 @@ typedef unsigned long ck_rv_t; typedef ck_rv_t (*ck_notify_t) (ck_session_handle_t session, ck_notification_t event, void *application); +struct ck_interface { + char * pInterfaceName; + void * pFunctionList; + ck_flags_t flags; +}; + +#define CKF_INTERFACE_FORK_SAFE (0x00000001UL) + /* Forward reference. */ struct ck_function_list; +struct ck_function_list_3_0; #define _CK_DECLARE_FUNCTION(name, args) \ typedef ck_rv_t (*CK_ ## name) args; \ @@ -774,7 +1047,7 @@ _CK_DECLARE_FUNCTION (C_SetOperationState, unsigned char *operation_state, unsigned long operation_state_len, ck_object_handle_t encryption_key, - ck_object_handle_t authentiation_key)); + ck_object_handle_t authentication_key)); _CK_DECLARE_FUNCTION (C_Login, (ck_session_handle_t session, ck_user_type_t user_type, unsigned char *pin, unsigned long pin_len)); @@ -999,6 +1272,147 @@ _CK_DECLARE_FUNCTION (C_GenerateRandom, _CK_DECLARE_FUNCTION (C_GetFunctionStatus, (ck_session_handle_t session)); _CK_DECLARE_FUNCTION (C_CancelFunction, (ck_session_handle_t session)); +_CK_DECLARE_FUNCTION (C_GetInterfaceList, + (struct ck_interface *interfaces_list, + unsigned long *count)); +_CK_DECLARE_FUNCTION (C_GetInterface, + (unsigned char *interface_name, + struct ck_version *version, + struct ck_interface **interface_ptr, + ck_flags_t flags)); + +_CK_DECLARE_FUNCTION (C_LoginUser, + (ck_session_handle_t session, + ck_user_type_t user_type, + unsigned char *pin, + unsigned long pin_len, + unsigned char *username, + unsigned long username_len)); + +_CK_DECLARE_FUNCTION (C_SessionCancel, + (ck_session_handle_t session, + ck_flags_t flags)); + +_CK_DECLARE_FUNCTION (C_MessageEncryptInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t key)); +_CK_DECLARE_FUNCTION (C_EncryptMessage, + (ck_session_handle_t session, + void *parameter, + unsigned long parameter_len, + unsigned char *associated_data, + unsigned long associated_data_len, + unsigned char *plaintext, + unsigned long plaintext_len, + unsigned char *ciphertext, + unsigned long *ciphertext_len)); +_CK_DECLARE_FUNCTION (C_EncryptMessageBegin, + (ck_session_handle_t session, + void *parameter, + unsigned long parameter_len, + unsigned char *associated_data, + unsigned long associated_data_len)); +_CK_DECLARE_FUNCTION (C_EncryptMessageNext, + (ck_session_handle_t session, + void *parameter, + unsigned long parameter_len, + unsigned char *plaintext_part, + unsigned long plaintext_part_len, + unsigned char *ciphertext_part, + unsigned long *ciphertext_part_len, + ck_flags_t flags)); +_CK_DECLARE_FUNCTION (C_MessageEncryptFinal, + (ck_session_handle_t session)); + +_CK_DECLARE_FUNCTION (C_MessageDecryptInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t key)); +_CK_DECLARE_FUNCTION (C_DecryptMessage, + (ck_session_handle_t session, + void *parameter, + unsigned long parameter_len, + unsigned char *associated_data, + unsigned long associated_data_len, + unsigned char *ciphertext, + unsigned long ciphertext_len, + unsigned char *plaintext, + unsigned long *plaintext_len)); +_CK_DECLARE_FUNCTION (C_DecryptMessageBegin, + (ck_session_handle_t session, + void *parameter, + unsigned long parameter_len, + unsigned char *associated_data, + unsigned long associated_data_len)); +_CK_DECLARE_FUNCTION (C_DecryptMessageNext, + (ck_session_handle_t session, + void *parameter, + unsigned long parameter_len, + unsigned char *ciphertext_part, + unsigned long ciphertext_part_len, + unsigned char *plaintext_part, + unsigned long *plaintext_part_len, + ck_flags_t flags)); +_CK_DECLARE_FUNCTION (C_MessageDecryptFinal, + (ck_session_handle_t session)); + +_CK_DECLARE_FUNCTION (C_MessageSignInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t key)); +_CK_DECLARE_FUNCTION (C_SignMessage, + (ck_session_handle_t session, + void *parameter, + unsigned long parameter_len, + unsigned char *data, + unsigned long data_len, + unsigned char *signature, + unsigned long *signature_len)); +_CK_DECLARE_FUNCTION (C_SignMessageBegin, + (ck_session_handle_t session, + void *parameter, + unsigned long parameter_len)); +_CK_DECLARE_FUNCTION (C_SignMessageNext, + (ck_session_handle_t session, + void *parameter, + unsigned long parameter_len, + unsigned char *data, + unsigned long data_len, + unsigned char *signature, + unsigned long *signature_len)); +_CK_DECLARE_FUNCTION (C_MessageSignFinal, + (ck_session_handle_t session)); + +_CK_DECLARE_FUNCTION (C_MessageVerifyInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t key)); +_CK_DECLARE_FUNCTION (C_VerifyMessage, + (ck_session_handle_t session, + void *parameter, + unsigned long parameter_len, + unsigned char *data, + unsigned long data_len, + unsigned char *signature, + unsigned long signature_len)); +_CK_DECLARE_FUNCTION (C_VerifyMessageBegin, + (ck_session_handle_t session, + void *parameter, + unsigned long parameter_len)); +_CK_DECLARE_FUNCTION (C_VerifyMessageNext, + (ck_session_handle_t session, + void *parameter, + unsigned long parameter_len, + unsigned char *data, + unsigned long data_len, + unsigned char *signature, + unsigned long signature_len)); +_CK_DECLARE_FUNCTION (C_MessageVerifyFinal, + (ck_session_handle_t session)); + +/* Flags in Message-based encryption/decryption API */ +#define CKF_END_OF_MESSAGE (0x00000001UL) struct ck_function_list { @@ -1073,6 +1487,105 @@ struct ck_function_list CK_C_WaitForSlotEvent C_WaitForSlotEvent; }; +struct ck_function_list_3_0 +{ + struct ck_version version; + CK_C_Initialize C_Initialize; + CK_C_Finalize C_Finalize; + CK_C_GetInfo C_GetInfo; + CK_C_GetFunctionList C_GetFunctionList; + CK_C_GetSlotList C_GetSlotList; + CK_C_GetSlotInfo C_GetSlotInfo; + CK_C_GetTokenInfo C_GetTokenInfo; + CK_C_GetMechanismList C_GetMechanismList; + CK_C_GetMechanismInfo C_GetMechanismInfo; + CK_C_InitToken C_InitToken; + CK_C_InitPIN C_InitPIN; + CK_C_SetPIN C_SetPIN; + CK_C_OpenSession C_OpenSession; + CK_C_CloseSession C_CloseSession; + CK_C_CloseAllSessions C_CloseAllSessions; + CK_C_GetSessionInfo C_GetSessionInfo; + CK_C_GetOperationState C_GetOperationState; + CK_C_SetOperationState C_SetOperationState; + CK_C_Login C_Login; + CK_C_Logout C_Logout; + CK_C_CreateObject C_CreateObject; + CK_C_CopyObject C_CopyObject; + CK_C_DestroyObject C_DestroyObject; + CK_C_GetObjectSize C_GetObjectSize; + CK_C_GetAttributeValue C_GetAttributeValue; + CK_C_SetAttributeValue C_SetAttributeValue; + CK_C_FindObjectsInit C_FindObjectsInit; + CK_C_FindObjects C_FindObjects; + CK_C_FindObjectsFinal C_FindObjectsFinal; + CK_C_EncryptInit C_EncryptInit; + CK_C_Encrypt C_Encrypt; + CK_C_EncryptUpdate C_EncryptUpdate; + CK_C_EncryptFinal C_EncryptFinal; + CK_C_DecryptInit C_DecryptInit; + CK_C_Decrypt C_Decrypt; + CK_C_DecryptUpdate C_DecryptUpdate; + CK_C_DecryptFinal C_DecryptFinal; + CK_C_DigestInit C_DigestInit; + CK_C_Digest C_Digest; + CK_C_DigestUpdate C_DigestUpdate; + CK_C_DigestKey C_DigestKey; + CK_C_DigestFinal C_DigestFinal; + CK_C_SignInit C_SignInit; + CK_C_Sign C_Sign; + CK_C_SignUpdate C_SignUpdate; + CK_C_SignFinal C_SignFinal; + CK_C_SignRecoverInit C_SignRecoverInit; + CK_C_SignRecover C_SignRecover; + CK_C_VerifyInit C_VerifyInit; + CK_C_Verify C_Verify; + CK_C_VerifyUpdate C_VerifyUpdate; + CK_C_VerifyFinal C_VerifyFinal; + CK_C_VerifyRecoverInit C_VerifyRecoverInit; + CK_C_VerifyRecover C_VerifyRecover; + CK_C_DigestEncryptUpdate C_DigestEncryptUpdate; + CK_C_DecryptDigestUpdate C_DecryptDigestUpdate; + CK_C_SignEncryptUpdate C_SignEncryptUpdate; + CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate; + CK_C_GenerateKey C_GenerateKey; + CK_C_GenerateKeyPair C_GenerateKeyPair; + CK_C_WrapKey C_WrapKey; + CK_C_UnwrapKey C_UnwrapKey; + CK_C_DeriveKey C_DeriveKey; + CK_C_SeedRandom C_SeedRandom; + CK_C_GenerateRandom C_GenerateRandom; + CK_C_GetFunctionStatus C_GetFunctionStatus; + CK_C_CancelFunction C_CancelFunction; + CK_C_WaitForSlotEvent C_WaitForSlotEvent; + /* PKCS #11 3.0 functions */ + CK_C_GetInterfaceList C_GetInterfaceList; + CK_C_GetInterface C_GetInterface; + CK_C_LoginUser C_LoginUser; + CK_C_SessionCancel C_SessionCancel; + CK_C_MessageEncryptInit C_MessageEncryptInit; + CK_C_EncryptMessage C_EncryptMessage; + CK_C_EncryptMessageBegin C_EncryptMessageBegin; + CK_C_EncryptMessageNext C_EncryptMessageNext; + CK_C_MessageEncryptFinal C_MessageEncryptFinal; + CK_C_MessageDecryptInit C_MessageDecryptInit; + CK_C_DecryptMessage C_DecryptMessage; + CK_C_DecryptMessageBegin C_DecryptMessageBegin; + CK_C_DecryptMessageNext C_DecryptMessageNext; + CK_C_MessageDecryptFinal C_MessageDecryptFinal; + CK_C_MessageSignInit C_MessageSignInit; + CK_C_SignMessage C_SignMessage; + CK_C_SignMessageBegin C_SignMessageBegin; + CK_C_SignMessageNext C_SignMessageNext; + CK_C_MessageSignFinal C_MessageSignFinal; + CK_C_MessageVerifyInit C_MessageVerifyInit; + CK_C_VerifyMessage C_VerifyMessage; + CK_C_VerifyMessageBegin C_VerifyMessageBegin; + CK_C_VerifyMessageNext C_VerifyMessageNext; + CK_C_MessageVerifyFinal C_MessageVerifyFinal; +}; + + typedef ck_rv_t (*ck_createmutex_t) (void **mutex); typedef ck_rv_t (*ck_destroymutex_t) (void *mutex); @@ -1091,96 +1604,97 @@ struct ck_c_initialize_args }; -#define CKF_LIBRARY_CANT_CREATE_OS_THREADS (1 << 0) -#define CKF_OS_LOCKING_OK (1 << 1) - -#define CKR_OK (0) -#define CKR_CANCEL (1) -#define CKR_HOST_MEMORY (2) -#define CKR_SLOT_ID_INVALID (3) -#define CKR_GENERAL_ERROR (5) -#define CKR_FUNCTION_FAILED (6) -#define CKR_ARGUMENTS_BAD (7) -#define CKR_NO_EVENT (8) -#define CKR_NEED_TO_CREATE_THREADS (9) -#define CKR_CANT_LOCK (0xa) -#define CKR_ATTRIBUTE_READ_ONLY (0x10) -#define CKR_ATTRIBUTE_SENSITIVE (0x11) -#define CKR_ATTRIBUTE_TYPE_INVALID (0x12) -#define CKR_ATTRIBUTE_VALUE_INVALID (0x13) -#define CKR_DATA_INVALID (0x20) -#define CKR_DATA_LEN_RANGE (0x21) -#define CKR_DEVICE_ERROR (0x30) -#define CKR_DEVICE_MEMORY (0x31) -#define CKR_DEVICE_REMOVED (0x32) -#define CKR_ENCRYPTED_DATA_INVALID (0x40) -#define CKR_ENCRYPTED_DATA_LEN_RANGE (0x41) -#define CKR_FUNCTION_CANCELED (0x50) -#define CKR_FUNCTION_NOT_PARALLEL (0x51) -#define CKR_FUNCTION_NOT_SUPPORTED (0x54) -#define CKR_KEY_HANDLE_INVALID (0x60) -#define CKR_KEY_SIZE_RANGE (0x62) -#define CKR_KEY_TYPE_INCONSISTENT (0x63) -#define CKR_KEY_NOT_NEEDED (0x64) -#define CKR_KEY_CHANGED (0x65) -#define CKR_KEY_NEEDED (0x66) -#define CKR_KEY_INDIGESTIBLE (0x67) -#define CKR_KEY_FUNCTION_NOT_PERMITTED (0x68) -#define CKR_KEY_NOT_WRAPPABLE (0x69) -#define CKR_KEY_UNEXTRACTABLE (0x6a) -#define CKR_MECHANISM_INVALID (0x70) -#define CKR_MECHANISM_PARAM_INVALID (0x71) -#define CKR_OBJECT_HANDLE_INVALID (0x82) -#define CKR_OPERATION_ACTIVE (0x90) -#define CKR_OPERATION_NOT_INITIALIZED (0x91) -#define CKR_PIN_INCORRECT (0xa0) -#define CKR_PIN_INVALID (0xa1) -#define CKR_PIN_LEN_RANGE (0xa2) -#define CKR_PIN_EXPIRED (0xa3) -#define CKR_PIN_LOCKED (0xa4) -#define CKR_SESSION_CLOSED (0xb0) -#define CKR_SESSION_COUNT (0xb1) -#define CKR_SESSION_HANDLE_INVALID (0xb3) -#define CKR_SESSION_PARALLEL_NOT_SUPPORTED (0xb4) -#define CKR_SESSION_READ_ONLY (0xb5) -#define CKR_SESSION_EXISTS (0xb6) -#define CKR_SESSION_READ_ONLY_EXISTS (0xb7) -#define CKR_SESSION_READ_WRITE_SO_EXISTS (0xb8) -#define CKR_SIGNATURE_INVALID (0xc0) -#define CKR_SIGNATURE_LEN_RANGE (0xc1) -#define CKR_TEMPLATE_INCOMPLETE (0xd0) -#define CKR_TEMPLATE_INCONSISTENT (0xd1) -#define CKR_TOKEN_NOT_PRESENT (0xe0) -#define CKR_TOKEN_NOT_RECOGNIZED (0xe1) -#define CKR_TOKEN_WRITE_PROTECTED (0xe2) -#define CKR_UNWRAPPING_KEY_HANDLE_INVALID (0xf0) -#define CKR_UNWRAPPING_KEY_SIZE_RANGE (0xf1) -#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT (0xf2) -#define CKR_USER_ALREADY_LOGGED_IN (0x100) -#define CKR_USER_NOT_LOGGED_IN (0x101) -#define CKR_USER_PIN_NOT_INITIALIZED (0x102) -#define CKR_USER_TYPE_INVALID (0x103) -#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN (0x104) -#define CKR_USER_TOO_MANY_TYPES (0x105) -#define CKR_WRAPPED_KEY_INVALID (0x110) -#define CKR_WRAPPED_KEY_LEN_RANGE (0x112) -#define CKR_WRAPPING_KEY_HANDLE_INVALID (0x113) -#define CKR_WRAPPING_KEY_SIZE_RANGE (0x114) -#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT (0x115) -#define CKR_RANDOM_SEED_NOT_SUPPORTED (0x120) -#define CKR_RANDOM_NO_RNG (0x121) -#define CKR_DOMAIN_PARAMS_INVALID (0x130) -#define CKR_BUFFER_TOO_SMALL (0x150) -#define CKR_SAVED_STATE_INVALID (0x160) -#define CKR_INFORMATION_SENSITIVE (0x170) -#define CKR_STATE_UNSAVEABLE (0x180) -#define CKR_CRYPTOKI_NOT_INITIALIZED (0x190) -#define CKR_CRYPTOKI_ALREADY_INITIALIZED (0x191) -#define CKR_MUTEX_BAD (0x1a0) -#define CKR_MUTEX_NOT_LOCKED (0x1a1) -#define CKR_FUNCTION_REJECTED (0x200) -#define CKR_VENDOR_DEFINED (1U << 31) - +#define CKF_LIBRARY_CANT_CREATE_OS_THREADS (1UL << 0) +#define CKF_OS_LOCKING_OK (1UL << 1) + +#define CKR_OK (0UL) +#define CKR_CANCEL (1UL) +#define CKR_HOST_MEMORY (2UL) +#define CKR_SLOT_ID_INVALID (3UL) +#define CKR_GENERAL_ERROR (5UL) +#define CKR_FUNCTION_FAILED (6UL) +#define CKR_ARGUMENTS_BAD (7UL) +#define CKR_NO_EVENT (8UL) +#define CKR_NEED_TO_CREATE_THREADS (9UL) +#define CKR_CANT_LOCK (0xaUL) +#define CKR_ATTRIBUTE_READ_ONLY (0x10UL) +#define CKR_ATTRIBUTE_SENSITIVE (0x11UL) +#define CKR_ATTRIBUTE_TYPE_INVALID (0x12UL) +#define CKR_ATTRIBUTE_VALUE_INVALID (0x13UL) +#define CKR_ACTION_PROHIBITED (0x1BUL) +#define CKR_DATA_INVALID (0x20UL) +#define CKR_DATA_LEN_RANGE (0x21UL) +#define CKR_DEVICE_ERROR (0x30UL) +#define CKR_DEVICE_MEMORY (0x31UL) +#define CKR_DEVICE_REMOVED (0x32UL) +#define CKR_ENCRYPTED_DATA_INVALID (0x40UL) +#define CKR_ENCRYPTED_DATA_LEN_RANGE (0x41UL) +#define CKR_FUNCTION_CANCELED (0x50UL) +#define CKR_FUNCTION_NOT_PARALLEL (0x51UL) +#define CKR_FUNCTION_NOT_SUPPORTED (0x54UL) +#define CKR_KEY_HANDLE_INVALID (0x60UL) +#define CKR_KEY_SIZE_RANGE (0x62UL) +#define CKR_KEY_TYPE_INCONSISTENT (0x63UL) +#define CKR_KEY_NOT_NEEDED (0x64UL) +#define CKR_KEY_CHANGED (0x65UL) +#define CKR_KEY_NEEDED (0x66UL) +#define CKR_KEY_INDIGESTIBLE (0x67UL) +#define CKR_KEY_FUNCTION_NOT_PERMITTED (0x68UL) +#define CKR_KEY_NOT_WRAPPABLE (0x69UL) +#define CKR_KEY_UNEXTRACTABLE (0x6aUL) +#define CKR_MECHANISM_INVALID (0x70UL) +#define CKR_MECHANISM_PARAM_INVALID (0x71UL) +#define CKR_OBJECT_HANDLE_INVALID (0x82UL) +#define CKR_OPERATION_ACTIVE (0x90UL) +#define CKR_OPERATION_NOT_INITIALIZED (0x91UL) +#define CKR_PIN_INCORRECT (0xa0UL) +#define CKR_PIN_INVALID (0xa1UL) +#define CKR_PIN_LEN_RANGE (0xa2UL) +#define CKR_PIN_EXPIRED (0xa3UL) +#define CKR_PIN_LOCKED (0xa4UL) +#define CKR_SESSION_CLOSED (0xb0UL) +#define CKR_SESSION_COUNT (0xb1UL) +#define CKR_SESSION_HANDLE_INVALID (0xb3UL) +#define CKR_SESSION_PARALLEL_NOT_SUPPORTED (0xb4UL) +#define CKR_SESSION_READ_ONLY (0xb5UL) +#define CKR_SESSION_EXISTS (0xb6UL) +#define CKR_SESSION_READ_ONLY_EXISTS (0xb7UL) +#define CKR_SESSION_READ_WRITE_SO_EXISTS (0xb8UL) +#define CKR_SIGNATURE_INVALID (0xc0UL) +#define CKR_SIGNATURE_LEN_RANGE (0xc1UL) +#define CKR_TEMPLATE_INCOMPLETE (0xd0UL) +#define CKR_TEMPLATE_INCONSISTENT (0xd1UL) +#define CKR_TOKEN_NOT_PRESENT (0xe0UL) +#define CKR_TOKEN_NOT_RECOGNIZED (0xe1UL) +#define CKR_TOKEN_WRITE_PROTECTED (0xe2UL) +#define CKR_UNWRAPPING_KEY_HANDLE_INVALID (0xf0UL) +#define CKR_UNWRAPPING_KEY_SIZE_RANGE (0xf1UL) +#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT (0xf2UL) +#define CKR_USER_ALREADY_LOGGED_IN (0x100UL) +#define CKR_USER_NOT_LOGGED_IN (0x101UL) +#define CKR_USER_PIN_NOT_INITIALIZED (0x102UL) +#define CKR_USER_TYPE_INVALID (0x103UL) +#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN (0x104UL) +#define CKR_USER_TOO_MANY_TYPES (0x105UL) +#define CKR_WRAPPED_KEY_INVALID (0x110UL) +#define CKR_WRAPPED_KEY_LEN_RANGE (0x112UL) +#define CKR_WRAPPING_KEY_HANDLE_INVALID (0x113UL) +#define CKR_WRAPPING_KEY_SIZE_RANGE (0x114UL) +#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT (0x115UL) +#define CKR_RANDOM_SEED_NOT_SUPPORTED (0x120UL) +#define CKR_RANDOM_NO_RNG (0x121UL) +#define CKR_DOMAIN_PARAMS_INVALID (0x130UL) +#define CKR_CURVE_NOT_SUPPORTED (0x140UL) +#define CKR_BUFFER_TOO_SMALL (0x150UL) +#define CKR_SAVED_STATE_INVALID (0x160UL) +#define CKR_INFORMATION_SENSITIVE (0x170UL) +#define CKR_STATE_UNSAVEABLE (0x180UL) +#define CKR_CRYPTOKI_NOT_INITIALIZED (0x190UL) +#define CKR_CRYPTOKI_ALREADY_INITIALIZED (0x191UL) +#define CKR_MUTEX_BAD (0x1a0UL) +#define CKR_MUTEX_NOT_LOCKED (0x1a1UL) +#define CKR_FUNCTION_REJECTED (0x200UL) +#define CKR_VENDOR_DEFINED (1UL << 31) /* Compatibility layer. */ @@ -1216,6 +1730,22 @@ typedef void **CK_VOID_PTR_PTR; #endif #endif +typedef struct CK_HKDF_PARAMS { + CK_BBOOL bExtract; + CK_BBOOL bExpand; + CK_MECHANISM_TYPE prfHashMechanism; + CK_ULONG ulSaltType; + CK_BYTE_PTR pSalt; + CK_ULONG ulSaltLen; + CK_OBJECT_HANDLE hSaltKey; + CK_BYTE_PTR pInfo; + CK_ULONG ulInfoLen; +} CK_HKDF_PARAMS; + +#define CKF_HKDF_SALT_NULL 0x00000001UL +#define CKF_HKDF_SALT_DATA 0x00000002UL +#define CKF_HKDF_SALT_KEY 0x00000004UL + typedef struct ck_version CK_VERSION; typedef struct ck_version *CK_VERSION_PTR; @@ -1247,16 +1777,26 @@ typedef struct ck_date *CK_DATE_PTR; typedef ck_mechanism_type_t *CK_MECHANISM_TYPE_PTR; +typedef ck_rsa_pkcs_mgf_type_t *CK_RSA_PKCS_MGF_TYPE_PTR; + typedef struct ck_mechanism CK_MECHANISM; typedef struct ck_mechanism *CK_MECHANISM_PTR; typedef struct ck_mechanism_info CK_MECHANISM_INFO; typedef struct ck_mechanism_info *CK_MECHANISM_INFO_PTR; +typedef struct ck_interface CK_INTERFACE; +typedef struct ck_interface *CK_INTERFACE_PTR; +typedef struct ck_interface **CK_INTERFACE_PTR_PTR; + typedef struct ck_function_list CK_FUNCTION_LIST; typedef struct ck_function_list *CK_FUNCTION_LIST_PTR; typedef struct ck_function_list **CK_FUNCTION_LIST_PTR_PTR; +typedef struct ck_function_list_3_0 CK_FUNCTION_LIST_3_0; +typedef struct ck_function_list_3_0 *CK_FUNCTION_LIST_3_0_PTR; +typedef struct ck_function_list_3_0 **CK_FUNCTION_LIST_3_0_PTR_PTR; + typedef struct ck_c_initialize_args CK_C_INITIALIZE_ARGS; typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR; @@ -1317,6 +1857,8 @@ typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR; #undef ck_mechanism_type_t +#undef ck_rsa_pkcs_mgf_type_t + #undef ck_mechanism #undef parameter #undef parameter_len @@ -1328,7 +1870,10 @@ typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR; #undef ck_rv_t #undef ck_notify_t +#undef ck_interface + #undef ck_function_list +#undef ck_function_list_3_0 #undef ck_createmutex_t #undef ck_destroymutex_t @@ -1344,7 +1889,6 @@ typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR; #endif /* CRYPTOKI_COMPAT */ - /* System dependencies. */ #if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32) #pragma pack(pop, cryptoki) diff --git a/platform-listen.c b/platform-listen.c index 42c4040..45df1f6 100644 --- a/platform-listen.c +++ b/platform-listen.c @@ -34,6 +34,13 @@ platform_pre_listen(void) /* Adjust out-of-memory killer so listening process is not killed */ oom_adjust_setup(); #endif +#ifdef LINUX_MEMLOCK_ONFAULT + /* + * Protect ourselves against kcompactd so that we are able to process + * new connections while it is active and migrating pages. + */ + memlock_onfault_setup(); +#endif } void @@ -82,3 +89,13 @@ platform_post_fork_child(void) #endif } +void platform_pre_session_start(void) +{ +#ifdef LINUX_MEMLOCK_ONFAULT + /* + * Memlock flags are dropped on fork, lock the memory again so that the + * child connection is also protected against kcompactd. + */ + memlock_onfault_setup(); +#endif +} diff --git a/platform.c b/platform.c index 4c4fe57..fd1a7a7 100644 --- a/platform.c +++ b/platform.c @@ -183,17 +183,26 @@ platform_locked_account(struct passwd *pw) /* check for locked account */ if (passwd && *passwd) { #ifdef LOCKED_PASSWD_STRING - if (strcmp(passwd, LOCKED_PASSWD_STRING) == 0) + if (strcmp(passwd, LOCKED_PASSWD_STRING) == 0) { + debug3_f("password matches locked string '%s'", + LOCKED_PASSWD_STRING); locked = 1; + } #endif #ifdef LOCKED_PASSWD_PREFIX if (strncmp(passwd, LOCKED_PASSWD_PREFIX, - strlen(LOCKED_PASSWD_PREFIX)) == 0) + strlen(LOCKED_PASSWD_PREFIX)) == 0) { + debug3_f("password matches locked prefix '%s'", + LOCKED_PASSWD_PREFIX); locked = 1; + } #endif #ifdef LOCKED_PASSWD_SUBSTR - if (strstr(passwd, LOCKED_PASSWD_SUBSTR)) + if (strstr(passwd, LOCKED_PASSWD_SUBSTR)) { + debug3_f("password matches locked substring '%s'", + LOCKED_PASSWD_SUBSTR); locked = 1; + } #endif } #ifdef USE_LIBIAF diff --git a/platform.h b/platform.h index 5dec232..08cbd22 100644 --- a/platform.h +++ b/platform.h @@ -24,6 +24,7 @@ void platform_pre_restart(void); void platform_post_listen(void); void platform_post_fork_parent(pid_t child_pid); void platform_post_fork_child(void); +void platform_pre_session_start(void); int platform_privileged_uidswap(void); void platform_setusercontext(struct passwd *); void platform_setusercontext_post_groups(struct passwd *); diff --git a/poly1305.c b/poly1305.c index de4d887..c674716 100644 --- a/poly1305.c +++ b/poly1305.c @@ -7,9 +7,7 @@ #include "includes.h" #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include "poly1305.h" diff --git a/progressmeter.c b/progressmeter.c index 4ee968e..22f510a 100644 --- a/progressmeter.c +++ b/progressmeter.c @@ -1,4 +1,4 @@ -/* $OpenBSD: progressmeter.c,v 1.53 2023/04/12 14:22:04 jsg Exp $ */ +/* $OpenBSD: progressmeter.c,v 1.57 2026/03/29 01:08:13 djm Exp $ */ /* * Copyright (c) 2003 Nils Nordman. All rights reserved. * @@ -46,7 +46,6 @@ #define DEFAULT_WINSIZE 80 #define MAX_WINSIZE 512 -#define PADDING 1 /* padding between the progress indicators */ #define UPDATE_INTERVAL 1 /* update the progress meter every second */ #define STALL_TIME 5 /* we're stalled after this many seconds */ @@ -68,7 +67,7 @@ static off_t end_pos; /* ending position of transfer */ static off_t cur_pos; /* transfer position as of last refresh */ static volatile off_t *counter; /* progress counter */ static long stalled; /* how long we have been stalled */ -static int bytes_per_second; /* current speed in bytes per second */ +static long long bytes_per_second; /* current speed in bytes per second */ static int win_size; /* terminal window size */ static volatile sig_atomic_t win_resized; /* for window resizing */ static volatile sig_atomic_t alarm_fired; @@ -94,15 +93,15 @@ format_rate(off_t bytes) bytes *= 100; for (i = 0; bytes >= 100*1000 && unit[i] != 'T'; i++) bytes = (bytes + 512) / 1024; + /* Display at least KB, even when rate is low or zero. */ if (i == 0) { i++; bytes = (bytes + 512) / 1024; } - snprintf(buf, sizeof(buf), "%3lld.%1lld%c%s", + snprintf(buf, sizeof(buf), "%3lld.%1lld%cB", (long long) (bytes + 5) / 100, (long long) (bytes + 5) / 10 % 10, - unit[i], - i ? "B" : " "); + unit[i]); return buf; } @@ -129,11 +128,12 @@ refresh_progress_meter(int force_update) double elapsed, now; int percent; off_t bytes_left; - int cur_speed; + long long cur_speed; int hours, minutes, seconds; int file_len, cols; - if ((!force_update && !alarm_fired && !win_resized) || !can_output()) + if (file == NULL || (!force_update && !alarm_fired && !win_resized) || + !can_output()) return; alarm_fired = 0; @@ -277,6 +277,7 @@ stop_progress_meter(void) refresh_progress_meter(1); atomicio(vwrite, STDOUT_FILENO, "\n", 1); + file = NULL; } static void diff --git a/readconf.c b/readconf.c index 9f55926..10cbd04 100644 --- a/readconf.c +++ b/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.392 2024/09/26 23:55:08 djm Exp $ */ +/* $OpenBSD: readconf.c,v 1.411 2026/03/30 07:18:24 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -22,42 +22,29 @@ #include #include -#include #include #include #include #include -#include -#ifdef HAVE_IFADDRS_H -# include -#endif +#include +#include #include #include -#ifdef HAVE_PATHS_H -# include -#endif +#include #include #include #include #include #include #include -#ifdef USE_SYSTEM_GLOB -# include -#else -# include "openbsd-compat/glob.h" -#endif -#ifdef HAVE_UTIL_H #include -#endif #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS) # include #endif #include "xmalloc.h" #include "ssh.h" -#include "ssherr.h" #include "cipher.h" #include "pathnames.h" #include "log.h" @@ -67,9 +54,9 @@ #include "match.h" #include "kex.h" #include "mac.h" -#include "uidswap.h" #include "myproposal.h" #include "digest.h" +#include "version.h" /* Format of the configuration file: @@ -133,11 +120,11 @@ */ static int read_config_file_depth(const char *filename, struct passwd *pw, - const char *host, const char *original_host, Options *options, - int flags, int *activep, int *want_final_pass, int depth); + const char *host, const char *original_host, const char *remote_command, + Options *options, int flags, int *activep, int *want_final_pass, int depth); static int process_config_line_depth(Options *options, struct passwd *pw, - const char *host, const char *original_host, char *line, - const char *filename, int linenum, int *activep, int flags, + const char *host, const char *original_host, const char *remote_command, + char *line, const char *filename, int linenum, int *activep, int flags, int *want_final_pass, int depth); /* Keyword tokens. */ @@ -179,6 +166,7 @@ typedef enum { oPubkeyAcceptedAlgorithms, oCASignatureAlgorithms, oProxyJump, oSecurityKeyProvider, oKnownHostsCommand, oRequiredRSASize, oEnableEscapeCommandline, oObscureKeystrokeTiming, oChannelTimeout, + oVersionAddendum, oRefuseConnection, oWarnWeakCrypto, oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported } OpCodes; @@ -329,6 +317,9 @@ static struct { { "enableescapecommandline", oEnableEscapeCommandline }, { "obscurekeystroketiming", oObscureKeystrokeTiming }, { "channeltimeout", oChannelTimeout }, + { "versionaddendum", oVersionAddendum }, + { "refuseconnection", oRefuseConnection }, + { "warnweakcrypto", oWarnWeakCrypto }, { NULL, oBadOption } }; @@ -708,7 +699,8 @@ expand_match_exec_or_include_path(const char *path, Options *options, static int match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, struct passwd *pw, const char *host_arg, const char *original_host, - int final_pass, int *want_final_pass, const char *filename, int linenum) + const char *remote_command, int final_pass, int *want_final_pass, + const char *filename, int linenum) { char *arg, *oattrib = NULL, *attrib = NULL, *cmd, *host, *criteria; const char *ruser; @@ -732,12 +724,12 @@ match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, debug2("checking match for '%s' host %s originally %s", full_line, host, original_host); while ((attrib = argv_next(acp, avp)) != NULL) { - attrib = oattrib = xstrdup(attrib); /* Terminate on comment */ if (*attrib == '#') { argv_consume(acp); break; } + attrib = oattrib = xstrdup(attrib); arg = criteria = NULL; this_result = 1; if ((negate = (attrib[0] == '!'))) @@ -764,19 +756,20 @@ match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, if (strcasecmp(attrib, "canonical") == 0 || strcasecmp(attrib, "final") == 0) { /* - * If the config requests "Match final" then remember - * this so we can perform a second pass later. + * If the config requests "Match final" without + * negation then remember this so we can perform a + * second pass later. */ if (strcasecmp(attrib, "final") == 0 && want_final_pass != NULL) - *want_final_pass = 1; + *want_final_pass |= !negate; r = !!final_pass; /* force bitmask member to boolean */ if (r == (negate ? 1 : 0)) this_result = result = 0; debug3("%.200s line %d: %smatched '%s'", filename, linenum, this_result ? "" : "not ", oattrib); - continue; + goto next; } /* Keep this list in sync with below */ @@ -785,16 +778,29 @@ match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, strprefix(attrib, "user=", 1) != NULL || strprefix(attrib, "localuser=", 1) != NULL || strprefix(attrib, "localnetwork=", 1) != NULL || + strprefix(attrib, "version=", 1) != NULL || strprefix(attrib, "tagged=", 1) != NULL || + strprefix(attrib, "command=", 1) != NULL || strprefix(attrib, "exec=", 1) != NULL) { arg = strchr(attrib, '='); *(arg++) = '\0'; - } else { - arg = argv_next(acp, avp); + } else if ((arg = argv_next(acp, avp)) == NULL) { + error("%.200s line %d: missing argument for Match '%s'", + filename, linenum, oattrib); + result = -1; + goto out; } - /* All other criteria require an argument */ - if (arg == NULL || *arg == '\0' || *arg == '#') { + /* + * All other criteria require an argument, though it may + * be the empty string for the "tagged" and "command" + * options. + */ + if (*arg == '\0' && + strcasecmp(attrib, "tagged") != 0 && + strcasecmp(attrib, "command") != 0) + arg = NULL; + if (arg == NULL || *arg == '#') { error("Missing Match criteria for %s", attrib); result = -1; goto out; @@ -828,9 +834,37 @@ match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, r = check_match_ifaddrs(arg) == 1; if (r == (negate ? 1 : 0)) this_result = result = 0; + } else if (strcasecmp(attrib, "version") == 0) { + criteria = xstrdup(SSH_RELEASE); + r = match_pattern_list(SSH_RELEASE, arg, 0) == 1; + if (r == (negate ? 1 : 0)) + this_result = result = 0; } else if (strcasecmp(attrib, "tagged") == 0) { criteria = xstrdup(options->tag == NULL ? "" : options->tag); + /* Special case: empty criteria matches empty arg */ + r = (*criteria == '\0') ? *arg == '\0' : + match_pattern_list(criteria, arg, 0) == 1; + if (r == (negate ? 1 : 0)) + this_result = result = 0; + } else if (strcasecmp(attrib, "command") == 0) { + criteria = xstrdup(remote_command == NULL ? + "" : remote_command); + /* Special case: empty criteria matches empty arg */ + r = (*criteria == '\0') ? *arg == '\0' : + match_pattern_list(criteria, arg, 0) == 1; + if (r == (negate ? 1 : 0)) + this_result = result = 0; + } else if (strcasecmp(attrib, "sessiontype") == 0) { + if (options->session_type == SESSION_TYPE_SUBSYSTEM) + criteria = xstrdup("subsystem"); + else if (options->session_type == SESSION_TYPE_NONE) + criteria = xstrdup("none"); + else if (remote_command != NULL && + *remote_command != '\0') + criteria = xstrdup("exec"); + else + criteria = xstrdup("shell"); r = match_pattern_list(criteria, arg, 0) == 1; if (r == (negate ? 1 : 0)) this_result = result = 0; @@ -846,7 +880,7 @@ match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, debug3("%.200s line %d: skipped exec " "\"%.100s\"", filename, linenum, cmd); free(cmd); - continue; + goto next; } r = execute_in_shell(cmd); if (r == -1) { @@ -870,6 +904,7 @@ match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, criteria == NULL ? "" : " \"", criteria == NULL ? "" : criteria, criteria == NULL ? "" : "\""); + next: free(criteria); free(oattrib); oattrib = attrib = NULL; @@ -1054,6 +1089,15 @@ static const struct multistate multistate_compression[] = { { "no", COMP_NONE }, { NULL, -1 } }; +/* XXX this will need to be replaced with a bitmask if we add more flags */ +static const struct multistate multistate_warnweakcrypto[] = { + { "true", 1 }, + { "false", 0 }, + { "yes", 1 }, + { "no", 0 }, + { "no-pq-kex", 0 }, + { NULL, -1 } +}; static int parse_multistate_value(const char *arg, const char *filename, int linenum, @@ -1078,18 +1122,19 @@ parse_multistate_value(const char *arg, const char *filename, int linenum, */ int process_config_line(Options *options, struct passwd *pw, const char *host, - const char *original_host, char *line, const char *filename, - int linenum, int *activep, int flags) + const char *original_host, const char *remote_command, char *line, + const char *filename, int linenum, int *activep, int flags) { return process_config_line_depth(options, pw, host, original_host, - line, filename, linenum, activep, flags, NULL, 0); + remote_command, line, filename, linenum, activep, flags, NULL, 0); } #define WHITESPACE " \t\r\n" static int process_config_line_depth(Options *options, struct passwd *pw, const char *host, - const char *original_host, char *line, const char *filename, - int linenum, int *activep, int flags, int *want_final_pass, int depth) + const char *original_host, const char *remote_command, char *line, + const char *filename, int linenum, int *activep, int flags, + int *want_final_pass, int depth) { char *str, **charptr, *endofnumber, *keyword, *arg, *arg2, *p; char **cpptr, ***cppptr, fwdarg[256]; @@ -1483,9 +1528,6 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, case oProxyCommand: charptr = &options->proxy_command; - /* Ignore ProxyCommand if ProxyJump already specified */ - if (options->jump_host != NULL) - charptr = &options->jump_host; /* Skip below */ parse_command: if (str == NULL) { error("%.200s line %d: Missing argument.", @@ -1506,7 +1548,7 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, } len = strspn(str, WHITESPACE "="); /* XXX use argv? */ - if (parse_jump(str + len, options, *activep) == -1) { + if (parse_jump(str + len, options, cmdline, *activep) == -1) { error("%.200s line %d: Invalid ProxyJump \"%s\"", filename, linenum, str + len); goto out; @@ -1826,8 +1868,8 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, goto out; } value = match_cfg_line(options, str, &ac, &av, pw, host, - original_host, flags & SSHCONF_FINAL, want_final_pass, - filename, linenum); + original_host, remote_command, flags & SSHCONF_FINAL, + want_final_pass, filename, linenum); if (value < 0) { error("%.200s line %d: Bad Match condition", filename, linenum); @@ -2079,8 +2121,8 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, gl.gl_pathv[i], depth, oactive ? "" : " (parse only)"); r = read_config_file_depth(gl.gl_pathv[i], - pw, host, original_host, options, - flags | SSHCONF_CHECKPERM | + pw, host, original_host, remote_command, + options, flags | SSHCONF_CHECKPERM | (oactive ? 0 : SSHCONF_NEVERMATCH), activep, want_final_pass, depth + 1); if (r != 1 && errno != ENOENT) { @@ -2112,6 +2154,12 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, filename, linenum, arg); goto out; } + if (value == INT_MIN) { + debug("%s line %d: Deprecated IPQoS value \"%s\" " + "ignored - using system default instead. Consider" + " using DSCP values.", filename, linenum, arg); + value = INT_MAX; + } arg = argv_next(&ac, &av); if (arg == NULL) value2 = value; @@ -2120,6 +2168,12 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, filename, linenum, arg); goto out; } + if (value2 == INT_MIN) { + debug("%s line %d: Deprecated IPQoS value \"%s\" " + "ignored - using system default instead. Consider" + " using DSCP values.", filename, linenum, arg); + value2 = INT_MAX; + } if (*activep && options->ip_qos_interactive == -1) { options->ip_qos_interactive = value; options->ip_qos_bulk = value2; @@ -2266,8 +2320,38 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, goto parse_flag; case oRevokedHostKeys: - charptr = &options->revoked_host_keys; - goto parse_string; + uintptr = &options->num_revoked_host_keys; + cppptr = &options->revoked_host_keys; + found = *uintptr == 0; + while ((arg = argv_next(&ac, &av)) != NULL) { + if (*arg == '\0') { + error("%s line %d: keyword %s empty argument", + filename, linenum, keyword); + goto out; + } + /* Allow "none" only in first position */ + if (strcasecmp(arg, "none") == 0) { + if (nstrs > 0 || ac > 0) { + error("%s line %d: keyword %s \"none\" " + "argument must appear alone.", + filename, linenum, keyword); + goto out; + } + } + opt_array_append(filename, linenum, keyword, + &strs, &nstrs, arg); + } + if (nstrs == 0) { + fatal("%s line %d: no %s specified", + filename, linenum, keyword); + } + if (found && *activep) { + *cppptr = strs; + *uintptr = nstrs; + strs = NULL; /* transferred */ + nstrs = 0; + } + break; case oFingerprintHash: intptr = &options->fingerprint_hash; @@ -2367,6 +2451,11 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, intptr = &options->required_rsa_size; goto parse_int; + case oWarnWeakCrypto: + intptr = &options->warn_weak_crypto; + multistate_ptr = multistate_warnweakcrypto; + goto parse_multistate; + case oObscureKeystrokeTiming: value = -1; while ((arg = argv_next(&ac, &av)) != NULL) { @@ -2440,6 +2529,41 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, } break; + case oVersionAddendum: + if (str == NULL || *str == '\0') + fatal("%s line %d: %s missing argument.", + filename, linenum, keyword); + len = strspn(str, WHITESPACE); + if (strchr(str + len, '\r') != NULL) { + fatal("%.200s line %d: Invalid %s argument", + filename, linenum, keyword); + } + if ((arg = strchr(line, '#')) != NULL) { + *arg = '\0'; + rtrim(line); + } + if (*activep && options->version_addendum == NULL) { + if (strcasecmp(str + len, "none") == 0) + options->version_addendum = xstrdup(""); + else + options->version_addendum = xstrdup(str + len); + } + argv_consume(&ac); + break; + + case oRefuseConnection: + arg = argv_next(&ac, &av); + if (!arg || *arg == '\0') { + error("%.200s line %d: Missing argument.", + filename, linenum); + goto out; + } + if (*activep) { + fatal("%.200s line %d: RefuseConnection: %s", + filename, linenum, arg); + } + break; + case oDeprecated: debug("%s line %d: Deprecated option \"%s\"", filename, linenum, keyword); @@ -2481,20 +2605,20 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, */ int read_config_file(const char *filename, struct passwd *pw, const char *host, - const char *original_host, Options *options, int flags, + const char *original_host, const char *remote_command, Options *options, int flags, int *want_final_pass) { int active = 1; return read_config_file_depth(filename, pw, host, original_host, - options, flags, &active, want_final_pass, 0); + remote_command, options, flags, &active, want_final_pass, 0); } #define READCONF_MAX_DEPTH 16 static int read_config_file_depth(const char *filename, struct passwd *pw, - const char *host, const char *original_host, Options *options, - int flags, int *activep, int *want_final_pass, int depth) + const char *host, const char *original_host, const char *remote_command, + Options *options, int flags, int *activep, int *want_final_pass, int depth) { FILE *f; char *line = NULL; @@ -2534,8 +2658,8 @@ read_config_file_depth(const char *filename, struct passwd *pw, * line numbers later for error messages. */ if (process_config_line_depth(options, pw, host, original_host, - line, filename, linenum, activep, flags, want_final_pass, - depth) != 0) + remote_command, line, filename, linenum, activep, flags, + want_final_pass, depth) != 0) bad_options++; } free(line); @@ -2685,17 +2809,20 @@ initialize_options(Options * options) options->canonicalize_fallback_local = -1; options->canonicalize_hostname = -1; options->revoked_host_keys = NULL; + options->num_revoked_host_keys = 0; options->fingerprint_hash = -1; options->update_hostkeys = -1; options->hostbased_accepted_algos = NULL; options->pubkey_accepted_algos = NULL; options->known_hosts_command = NULL; options->required_rsa_size = -1; + options->warn_weak_crypto = -1; options->enable_escape_commandline = -1; options->obscure_keystroke_timing_interval = -1; options->tag = NULL; options->channel_timeouts = NULL; options->num_channel_timeouts = 0; + options->version_addendum = NULL; } /* @@ -2799,10 +2926,6 @@ fill_default_options(Options * options) _PATH_SSH_CLIENT_ID_ED25519, 0); add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_ED25519_SK, 0); - add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_XMSS, 0); -#ifdef WITH_DSA - add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_DSA, 0); -#endif } if (options->escape_char == -1) options->escape_char = '~'; @@ -2866,9 +2989,9 @@ fill_default_options(Options * options) if (options->visual_host_key == -1) options->visual_host_key = 0; if (options->ip_qos_interactive == -1) - options->ip_qos_interactive = IPTOS_DSCP_AF21; + options->ip_qos_interactive = IPTOS_DSCP_EF; if (options->ip_qos_bulk == -1) - options->ip_qos_bulk = IPTOS_DSCP_CS1; + options->ip_qos_bulk = IPTOS_DSCP_CS0; if (options->request_tty == -1) options->request_tty = REQUEST_TTY_AUTO; if (options->session_type == -1) @@ -2896,6 +3019,8 @@ fill_default_options(Options * options) #endif if (options->required_rsa_size == -1) options->required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE; + if (options->warn_weak_crypto == -1) + options->warn_weak_crypto = 1; if (options->enable_escape_commandline == -1) options->enable_escape_commandline = 0; if (options->obscure_keystroke_timing_interval == -1) { @@ -2923,6 +3048,7 @@ fill_default_options(Options * options) goto fail; \ } \ } while (0) + options->kex_algorithms_set = options->kex_algorithms != NULL; ASSEMBLE(ciphers, def_cipher, all_cipher); ASSEMBLE(macs, def_mac, all_mac); ASSEMBLE(kex_algorithms, def_kex, all_kex); @@ -2952,11 +3078,11 @@ fill_default_options(Options * options) CLEAR_ON_NONE(options->remote_command); CLEAR_ON_NONE(options->proxy_command); CLEAR_ON_NONE(options->control_path); - CLEAR_ON_NONE(options->revoked_host_keys); CLEAR_ON_NONE(options->pkcs11_provider); CLEAR_ON_NONE(options->sk_provider); CLEAR_ON_NONE(options->known_hosts_command); CLEAR_ON_NONE_ARRAY(channel_timeouts, num_channel_timeouts, "none"); + CLEAR_ON_NONE_ARRAY(revoked_host_keys, num_revoked_host_keys, "none"); #undef CLEAR_ON_NONE #undef CLEAR_ON_NONE_ARRAY if (options->jump_host != NULL && @@ -3067,6 +3193,7 @@ free_options(Options *o) free(o->permitted_cnames[i].source_list); free(o->permitted_cnames[i].target_list); } + FREE_ARRAY(u_int, o->num_revoked_host_keys, o->revoked_host_keys); free(o->revoked_host_keys); free(o->hostbased_accepted_algos); free(o->pubkey_accepted_algos); @@ -3298,65 +3425,116 @@ parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remo } int -parse_jump(const char *s, Options *o, int active) +ssh_valid_hostname(const char *s) { - char *orig, *sdup, *cp; - char *host = NULL, *user = NULL; - int r, ret = -1, port = -1, first; + size_t i; - active &= o->proxy_command == NULL && o->jump_host == NULL; + if (*s == '-') + return 0; + for (i = 0; s[i] != 0; i++) { + if (strchr("'`\"$\\;&<>|(){},", s[i]) != NULL || + isspace((u_char)s[i]) || iscntrl((u_char)s[i])) + return 0; + } + return 1; +} - orig = sdup = xstrdup(s); +int +ssh_valid_ruser(const char *s) +{ + size_t i; + + if (*s == '-') + return 0; + for (i = 0; s[i] != 0; i++) { + if (iscntrl((u_char)s[i])) + return 0; + if (strchr("'`\";&<>|(){}", s[i]) != NULL) + return 0; + /* Disallow '-' after whitespace */ + if (isspace((u_char)s[i]) && s[i + 1] == '-') + return 0; + /* Disallow \ in last position */ + if (s[i] == '\\' && s[i + 1] == '\0') + return 0; + } + return 1; +} + +int +parse_jump(const char *s, Options *o, int strict, int active) +{ + char *orig = NULL, *sdup = NULL, *cp; + char *tmp_user = NULL, *tmp_host = NULL, *host = NULL, *user = NULL; + int r, ret = -1, tmp_port = -1, port = -1, first = 1; + + if (strcasecmp(s, "none") == 0) { + if (active && o->jump_host == NULL) { + o->jump_host = xstrdup("none"); + o->jump_port = 0; + } + return 0; + } - /* Remove comment and trailing whitespace */ + orig = xstrdup(s); if ((cp = strchr(orig, '#')) != NULL) *cp = '\0'; rtrim(orig); - first = active; + active &= o->proxy_command == NULL && o->jump_host == NULL; + sdup = xstrdup(orig); do { - if (strcasecmp(s, "none") == 0) - break; + /* Work backwards through string */ if ((cp = strrchr(sdup, ',')) == NULL) cp = sdup; /* last */ else *cp++ = '\0'; - if (first) { - /* First argument and configuration is active */ - r = parse_ssh_uri(cp, &user, &host, &port); - if (r == -1 || (r == 1 && - parse_user_host_port(cp, &user, &host, &port) != 0)) + r = parse_ssh_uri(cp, &tmp_user, &tmp_host, &tmp_port); + if (r == -1 || (r == 1 && parse_user_host_port(cp, + &tmp_user, &tmp_host, &tmp_port) != 0)) + goto out; /* error already logged */ + if (strict) { + if (!ssh_valid_hostname(tmp_host)) { + error_f("invalid hostname \"%s\"", tmp_host); goto out; - } else { - /* Subsequent argument or inactive configuration */ - r = parse_ssh_uri(cp, NULL, NULL, NULL); - if (r == -1 || (r == 1 && - parse_user_host_port(cp, NULL, NULL, NULL) != 0)) + } + if (tmp_user != NULL && !ssh_valid_ruser(tmp_user)) { + error_f("invalid username \"%s\"", tmp_user); goto out; + } + } + if (first) { + user = tmp_user; + host = tmp_host; + port = tmp_port; + tmp_user = tmp_host = NULL; /* transferred */ } first = 0; /* only check syntax for subsequent hosts */ + free(tmp_user); + free(tmp_host); + tmp_user = tmp_host = NULL; + tmp_port = -1; } while (cp != sdup); + /* success */ if (active) { - if (strcasecmp(s, "none") == 0) { - o->jump_host = xstrdup("none"); - o->jump_port = 0; - } else { - o->jump_user = user; - o->jump_host = host; - o->jump_port = port; - o->proxy_command = xstrdup("none"); - user = host = NULL; - if ((cp = strrchr(s, ',')) != NULL && cp != s) { - o->jump_extra = xstrdup(s); - o->jump_extra[cp - s] = '\0'; - } + o->jump_user = user; + o->jump_host = host; + o->jump_port = port; + o->proxy_command = xstrdup("none"); + user = host = NULL; /* transferred */ + if (orig != NULL && (cp = strrchr(orig, ',')) != NULL) { + o->jump_extra = xstrdup(orig); + o->jump_extra[cp - orig] = '\0'; } } ret = 0; out: free(orig); + free(sdup); + free(tmp_user); + free(tmp_host); free(user); free(host); return ret; @@ -3410,6 +3588,8 @@ fmt_intarg(OpCodes code, int val) switch (code) { case oAddressFamily: return fmt_multistate_int(val, multistate_addressfamily); + case oCompression: + return fmt_multistate_int(val, multistate_compression); case oVerifyHostKeyDNS: case oUpdateHostkeys: return fmt_multistate_int(val, multistate_yesnoask); @@ -3608,6 +3788,7 @@ dump_client_config(Options *o, const char *host) dump_cfg_fmtint(oVisualHostKey, o->visual_host_key); dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys); dump_cfg_fmtint(oEnableEscapeCommandline, o->enable_escape_commandline); + dump_cfg_fmtint(oWarnWeakCrypto, o->warn_weak_crypto); /* Integer options */ dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots); @@ -3643,10 +3824,10 @@ dump_client_config(Options *o, const char *host) dump_cfg_string(oSecurityKeyProvider, o->sk_provider); dump_cfg_string(oPreferredAuthentications, o->preferred_authentications); dump_cfg_string(oPubkeyAcceptedAlgorithms, o->pubkey_accepted_algos); - dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys); dump_cfg_string(oXAuthLocation, o->xauth_location); dump_cfg_string(oKnownHostsCommand, o->known_hosts_command); dump_cfg_string(oTag, o->tag); + dump_cfg_string(oVersionAddendum, o->version_addendum); /* Forwards */ dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards); @@ -3659,6 +3840,7 @@ dump_client_config(Options *o, const char *host) dump_cfg_strarray(oCertificateFile, o->num_certificate_files, o->certificate_files); dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles); dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles); + dump_cfg_strarray_oneline(oRevokedHostKeys, o->num_revoked_host_keys, o->revoked_host_keys); dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env); dump_cfg_strarray(oSetEnv, o->num_setenv, o->setenv); dump_cfg_strarray_oneline(oLogVerbose, diff --git a/readconf.h b/readconf.h index 9447d5d..dbcb417 100644 --- a/readconf.h +++ b/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.156 2024/03/04 02:16:11 djm Exp $ */ +/* $OpenBSD: readconf.h,v 1.163 2026/03/30 07:18:24 djm Exp $ */ /* * Author: Tatu Ylonen @@ -19,7 +19,6 @@ /* Data structure for representing option data. */ #define SSH_MAX_HOSTS_FILES 32 -#define MAX_CANON_DOMAINS 32 #define PATH_MAX_SUN (sizeof((struct sockaddr_un *)0)->sun_path) struct allowed_cname { @@ -50,8 +49,8 @@ typedef struct { int strict_host_key_checking; /* Strict host key checking. */ int compression; /* Compress packets in both directions. */ int tcp_keep_alive; /* Set SO_KEEPALIVE. */ - int ip_qos_interactive; /* IP ToS/DSCP/class for interactive */ - int ip_qos_bulk; /* IP ToS/DSCP/class for bulk traffic */ + int ip_qos_interactive; /* DSCP value for interactive */ + int ip_qos_bulk; /* DSCP value for bulk traffic */ SyslogFacility log_facility; /* Facility for system logging. */ LogLevel log_level; /* Level for logging. */ u_int num_log_verbose; /* Verbose log overrides */ @@ -68,6 +67,7 @@ typedef struct { char *macs; /* SSH2 macs in order of preference. */ char *hostkeyalgorithms; /* SSH2 server key types in order of preference. */ char *kex_algorithms; /* SSH2 kex methods in order of preference. */ + int kex_algorithms_set; /* KexAlgorithms was set by the user */ char *ca_sign_algorithms; /* Allowed CA signature algorithms */ char *hostname; /* Real host to connect. */ char *tag; /* Configuration tag name. */ @@ -162,7 +162,8 @@ typedef struct { int num_permitted_cnames; struct allowed_cname *permitted_cnames; - char *revoked_host_keys; + u_int num_revoked_host_keys; + char **revoked_host_keys; int fingerprint_hash; @@ -181,10 +182,13 @@ typedef struct { int required_rsa_size; /* minimum size of RSA keys */ int enable_escape_commandline; /* ~C commandline */ int obscure_keystroke_timing_interval; + int warn_weak_crypto; char **channel_timeouts; /* inactivity timeout by channel type */ u_int num_channel_timeouts; + char *version_addendum; + char *ignored_unknown; /* Pattern list of unknown tokens to ignore */ } Options; @@ -239,11 +243,13 @@ int fill_default_options(Options *); void fill_default_options_for_canonicalization(Options *); void free_options(Options *o); int process_config_line(Options *, struct passwd *, const char *, - const char *, char *, const char *, int, int *, int); + const char *, const char *, char *, const char *, int, int *, int); int read_config_file(const char *, struct passwd *, const char *, - const char *, Options *, int, int *); + const char *, const char *, Options *, int, int *); int parse_forward(struct Forward *, const char *, int, int); -int parse_jump(const char *, Options *, int); +int ssh_valid_hostname(const char *); +int ssh_valid_ruser(const char *); +int parse_jump(const char *, Options *, int, int); int parse_ssh_uri(const char *, char **, char **, int *); int default_ssh_port(void); int option_clear_or_none(const char *); diff --git a/readpass.c b/readpass.c index d42b118..2502e52 100644 --- a/readpass.c +++ b/readpass.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readpass.c,v 1.71 2024/03/30 04:27:44 djm Exp $ */ +/* $OpenBSD: readpass.c,v 1.73 2026/02/14 00:18:34 jsg Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -30,9 +30,7 @@ #include #include -#ifdef HAVE_PATHS_H -# include -#endif +#include #include #include #include @@ -45,7 +43,6 @@ #include "pathnames.h" #include "log.h" #include "ssh.h" -#include "uidswap.h" static char * ssh_askpass(char *askpass, const char *msg, const char *env_hint) @@ -91,7 +88,7 @@ ssh_askpass(char *askpass, const char *msg, const char *env_hint) if (r <= 0) break; len += r; - } while (sizeof(buf) - 1 - len > 0); + } while (len < sizeof(buf) - 1); buf[len] = '\0'; close(p[0]); diff --git a/regress/Makefile b/regress/Makefile index 7f73497..ae45bd4 100644 --- a/regress/Makefile +++ b/regress/Makefile @@ -1,8 +1,8 @@ -# $OpenBSD: Makefile,v 1.135 2024/06/14 04:43:11 djm Exp $ +# $OpenBSD: Makefile,v 1.144 2026/03/30 07:19:02 djm Exp $ tests: prep file-tests t-exec unit -REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 +REGRESS_TARGETS= t1 t2 t3 t4 t5 t7 t9 t10 t11 t12 # File based tests file-tests: $(REGRESS_TARGETS) @@ -19,6 +19,7 @@ clean: for F in $(CLEANFILES); do rm -f $(OBJ)$$F; done rm -rf $(OBJ).putty rm -rf $(OBJ).dropbear + rm -rf $(OBJ).fakehome distclean: clean @@ -65,6 +66,7 @@ LTESTS= connect \ sftp-batch \ sftp-glob \ sftp-perm \ + sftp-resume \ sftp-uri \ reconfigure \ dynamic-forward \ @@ -105,16 +107,22 @@ LTESTS= connect \ knownhosts-command \ agent-restrict \ hostbased \ + password \ + kbdint \ channel-timeout \ connection-timeout \ match-subsystem \ agent-pkcs11-restrict \ agent-pkcs11-cert \ penalty \ - penalty-expire + penalty-expire \ + connect-bigconf \ + ssh-pkcs11 \ + ssh-tty \ + proxyjump INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers -INTEROP_TESTS+= dropbear-ciphers dropbear-kex +INTEROP_TESTS+= dropbear-ciphers dropbear-kex dropbear-server #INTEROP_TESTS+=ssh-com ssh-com-client ssh-com-keygen ssh-com-sftp EXTRA_TESTS= agent-pkcs11 @@ -129,9 +137,9 @@ CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \ ed25519-agent.pub ed25519 ed25519.pub empty.in \ expect failed-regress.log failed-ssh.log failed-sshd.log \ hkr.* host.ecdsa-sha2-nistp256 host.ecdsa-sha2-nistp384 \ - host.ecdsa-sha2-nistp521 host.ssh-dss host.ssh-ed25519 \ + host.ecdsa-sha2-nistp521 host.ssh-ed25519 \ host.ssh-rsa host_ca_key* host_krl_* host_revoked_* key.* \ - key.dsa-* key.ecdsa-* key.ed25519-512 \ + key.ecdsa-* key.ed25519-512 \ key.ed25519-512.pub key.rsa-* keys-command-args kh.* askpass \ known_hosts known_hosts-cert known_hosts.* krl-* ls.copy \ modpipe netcat no_identity_config \ @@ -148,7 +156,8 @@ CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \ sshd_proxy_orig t10.out t10.out.pub t12.out t12.out.pub \ t2.out t3.out t6.out1 t6.out2 t7.out t7.out.pub \ t8.out t8.out.pub t9.out t9.out.pub \ - timestamp testdata user_*key* user_ca* user_key* + timestamp testdata user_*key* user_ca* user_key* \ + pin.sh nopin.sh wrongpin.sh key.pub test.sh ctl-sock # Enable all malloc(3) randomisations and checks TEST_ENV= "MALLOC_OPTIONS=CFGJRSUX" @@ -190,36 +199,18 @@ t5: ${TEST_SSH_SSHKEYGEN} -Bf ${.CURDIR}/rsa_openssh.pub |\ awk '{print $$2}' | diff - ${.CURDIR}/t5.ok ; \ fi -t6: - set -xe ; if ${TEST_SSH_SSH} -Q key | grep -q "^ssh-dss" ; then \ - ${TEST_SSH_SSHKEYGEN} -if ${.CURDIR}/dsa_ssh2.prv > $(OBJ)/t6.out1 ; \ - ${TEST_SSH_SSHKEYGEN} -if ${.CURDIR}/dsa_ssh2.pub > $(OBJ)/t6.out2 ; \ - chmod 600 $(OBJ)/t6.out1 ; \ - ${TEST_SSH_SSHKEYGEN} -yf $(OBJ)/t6.out1 | diff - $(OBJ)/t6.out2 ; \ - fi $(OBJ)/t7.out: - set -xe ; if ${TEST_SSH_SSH} -Q key | grep -q "^ssh-dss" ; then \ + set -xe ; if ${TEST_SSH_SSH} -Q key | grep -q "^ssh-rsa" ; then \ ${TEST_SSH_SSHKEYGEN} -q -t rsa -N '' -f $@ ; \ fi t7: $(OBJ)/t7.out - set -xe ; if ${TEST_SSH_SSH} -Q key | grep -q "^ssh-dss" ; then \ + set -xe ; if ${TEST_SSH_SSH} -Q key | grep -q "^ssh-rsa" ; then \ ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t7.out > /dev/null ; \ ${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t7.out > /dev/null ; \ fi -$(OBJ)/t8.out: - set -xe ; if ssh -Q key | grep -q "^ssh-dss" ; then \ - ${TEST_SSH_SSHKEYGEN} -q -t dsa -N '' -f $@ ; \ - fi - -t8: $(OBJ)/t8.out - set -xe ; if ssh -Q key | grep -q "^ssh-dss" ; then \ - ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t8.out > /dev/null ; \ - ${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t8.out > /dev/null ; \ - fi - $(OBJ)/t9.out: ! ${TEST_SSH_SSH} -Q key-plain | grep ecdsa >/dev/null || \ ${TEST_SSH_SSHKEYGEN} -q -t ecdsa -N '' -f $@ @@ -239,7 +230,7 @@ t10: $(OBJ)/t10.out ${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t10.out > /dev/null t11: - set -xe ; if ${TEST_SSH_SSH} -Q key | grep -q "^ssh-dss" ; then \ + set -xe ; if ${TEST_SSH_SSH} -Q key | grep -q "^ssh-rsa" ; then \ ${TEST_SSH_SSHKEYGEN} -E sha256 -lf ${.CURDIR}/rsa_openssh.pub |\ awk '{print $$2}' | diff - ${.CURDIR}/t11.ok ; \ fi @@ -291,26 +282,33 @@ t-extra: ${EXTRA_TESTS:=.sh} interop: ${INTEROP_TARGETS} # Unit tests, built by top-level Makefile -unit: +unit unit-bench: set -e ; if test -z "${SKIP_UNIT}" ; then \ V="" ; \ test "x${USE_VALGRIND}" = "x" || \ V=${.CURDIR}/valgrind-unit.sh ; \ - $$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \ + ARGS=""; \ + test "x$@" = "xunit-bench" && ARGS="-b"; \ + test "x${UNITTEST_FAST}" = "x" || ARGS="$$ARGS -f"; \ + test "x${UNITTEST_SLOW}" = "x" || ARGS="$$ARGS -F"; \ + test "x${UNITTEST_VERBOSE}" = "x" || ARGS="$$ARGS -v"; \ + test "x${UNITTEST_BENCH_DETAIL}" = "x" || ARGS="$$ARGS -B"; \ + test "x${UNITTEST_BENCH_ONLY}" = "x" || ARGS="$$ARGS -O ${UNITTEST_BENCH_ONLY}"; \ + $$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf $${ARGS}; \ $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \ - -d ${.CURDIR}/unittests/sshkey/testdata ; \ + -d ${.CURDIR}/unittests/sshkey/testdata $${ARGS}; \ $$V ${.OBJDIR}/unittests/sshsig/test_sshsig \ - -d ${.CURDIR}/unittests/sshsig/testdata ; \ + -d ${.CURDIR}/unittests/sshsig/testdata $${ARGS}; \ $$V ${.OBJDIR}/unittests/authopt/test_authopt \ - -d ${.CURDIR}/unittests/authopt/testdata ; \ - $$V ${.OBJDIR}/unittests/bitmap/test_bitmap ; \ - $$V ${.OBJDIR}/unittests/conversion/test_conversion ; \ - $$V ${.OBJDIR}/unittests/kex/test_kex ; \ + -d ${.CURDIR}/unittests/authopt/testdata $${ARGS}; \ + $$V ${.OBJDIR}/unittests/bitmap/test_bitmap $${ARGS}; \ + $$V ${.OBJDIR}/unittests/conversion/test_conversion $${ARGS}; \ + $$V ${.OBJDIR}/unittests/kex/test_kex $${ARGS}; \ $$V ${.OBJDIR}/unittests/hostkeys/test_hostkeys \ - -d ${.CURDIR}/unittests/hostkeys/testdata ; \ - $$V ${.OBJDIR}/unittests/match/test_match ; \ - $$V ${.OBJDIR}/unittests/misc/test_misc ; \ + -d ${.CURDIR}/unittests/hostkeys/testdata $${ARGS}; \ + $$V ${.OBJDIR}/unittests/match/test_match $${ARGS}; \ + $$V ${.OBJDIR}/unittests/misc/test_misc $${ARGS}; \ if test "x${TEST_SSH_UTF8}" = "xyes" ; then \ - $$V ${.OBJDIR}/unittests/utf8/test_utf8 ; \ + $$V ${.OBJDIR}/unittests/utf8/test_utf8 $${ARGS}; \ fi \ fi diff --git a/regress/agent-pkcs11-cert.sh b/regress/agent-pkcs11-cert.sh index 4e8f748..551067d 100644 --- a/regress/agent-pkcs11-cert.sh +++ b/regress/agent-pkcs11-cert.sh @@ -1,15 +1,12 @@ -# $OpenBSD: agent-pkcs11-cert.sh,v 1.1 2023/12/18 14:50:08 djm Exp $ +# $OpenBSD: agent-pkcs11-cert.sh,v 1.3 2025/07/26 01:53:31 djm Exp $ # Placed in the Public Domain. tid="pkcs11 agent certificate test" -SSH_AUTH_SOCK="$OBJ/agent.sock" -export SSH_AUTH_SOCK LC_ALL=C export LC_ALL p11_setup || skip "No PKCS#11 library found" -rm -f $SSH_AUTH_SOCK $OBJ/agent.log rm -f $OBJ/output_* $OBJ/expect_* rm -f $OBJ/ca* @@ -19,74 +16,80 @@ $SSHKEYGEN -qs $OBJ/ca -I "ecdsa_key" -n $USER -z 1 ${SSH_SOFTHSM_DIR}/EC.pub || fatal "certify ECDSA key failed" $SSHKEYGEN -qs $OBJ/ca -I "rsa_key" -n $USER -z 2 ${SSH_SOFTHSM_DIR}/RSA.pub || fatal "certify RSA key failed" -$SSHKEYGEN -qs $OBJ/ca -I "ca_ca" -n $USER -z 3 $OBJ/ca.pub || +$SSHKEYGEN -qs $OBJ/ca -I "ed25519_key" -n $USER -z 3 \ + ${SSH_SOFTHSM_DIR}/ED25519.pub || + fatal "certify ed25519 key failed" +$SSHKEYGEN -qs $OBJ/ca -I "ca_ca" -n $USER -z 4 $OBJ/ca.pub || fatal "certify CA key failed" -rm -f $SSH_AUTH_SOCK -trace "start agent" -${SSHAGENT} ${EXTRA_AGENT_ARGS} -d -a $SSH_AUTH_SOCK > $OBJ/agent.log 2>&1 & -AGENT_PID=$! -trap "kill $AGENT_PID" EXIT -for x in 0 1 2 3 4 ; do - # Give it a chance to start - ${SSHADD} -l > /dev/null 2>&1 - r=$? - test $r -eq 1 && break - sleep 1 -done -if [ $r -ne 1 ]; then - fatal "ssh-add -l did not fail with exit code 1 (got $r)" -fi +start_ssh_agent -trace "load pkcs11 keys and certs" +verbose "load pkcs11 keys and certs" # Note: deliberately contains non-cert keys and non-matching cert on commandline p11_ssh_add -qs ${TEST_SSH_PKCS11} \ $OBJ/ca.pub \ + ${SSH_SOFTHSM_DIR}/ED25519.pub \ + ${SSH_SOFTHSM_DIR}/ED25519-cert.pub \ ${SSH_SOFTHSM_DIR}/EC.pub \ ${SSH_SOFTHSM_DIR}/EC-cert.pub \ ${SSH_SOFTHSM_DIR}/RSA.pub \ ${SSH_SOFTHSM_DIR}/RSA-cert.pub || fatal "failed to add keys" # Verify their presence +verbose "verify presence" cut -d' ' -f1-2 \ + ${SSH_SOFTHSM_DIR}/ED25519.pub \ ${SSH_SOFTHSM_DIR}/EC.pub \ ${SSH_SOFTHSM_DIR}/RSA.pub \ + ${SSH_SOFTHSM_DIR}/ED25519-cert.pub \ ${SSH_SOFTHSM_DIR}/EC-cert.pub \ ${SSH_SOFTHSM_DIR}/RSA-cert.pub | sort > $OBJ/expect_list $SSHADD -L | cut -d' ' -f1-2 | sort > $OBJ/output_list diff $OBJ/expect_list $OBJ/output_list # Verify that all can perform signatures. +verbose "check signatures" for x in ${SSH_SOFTHSM_DIR}/EC.pub ${SSH_SOFTHSM_DIR}/RSA.pub \ - ${SSH_SOFTHSM_DIR}/EC-cert.pub ${SSH_SOFTHSM_DIR}/RSA-cert.pub ; do + ${SSH_SOFTHSM_DIR}/EC-cert.pub ${SSH_SOFTHSM_DIR}/RSA-cert.pub \ + ${SSH_SOFTHSM_DIR}/ED25519.pub ${SSH_SOFTHSM_DIR}/ED25519-cert.pub ; do $SSHADD -T $x || fail "Signing failed for $x" done # Delete plain keys. +verbose "delete plain keys" $SSHADD -qd ${SSH_SOFTHSM_DIR}/EC.pub ${SSH_SOFTHSM_DIR}/RSA.pub +$SSHADD -qd ${SSH_SOFTHSM_DIR}/ED25519.pub # Verify that certs can still perform signatures. -for x in ${SSH_SOFTHSM_DIR}/EC-cert.pub ${SSH_SOFTHSM_DIR}/RSA-cert.pub ; do +verbose "reverify certificate signatures" +for x in ${SSH_SOFTHSM_DIR}/EC-cert.pub ${SSH_SOFTHSM_DIR}/RSA-cert.pub \ + ${SSH_SOFTHSM_DIR}/ED25519-cert.pub ; do $SSHADD -T $x || fail "Signing failed for $x" done $SSHADD -qD >/dev/null || fatal "clear agent failed" -trace "load pkcs11 certs only" +verbose "load pkcs11 certs only" p11_ssh_add -qCs ${TEST_SSH_PKCS11} \ $OBJ/ca.pub \ ${SSH_SOFTHSM_DIR}/EC.pub \ ${SSH_SOFTHSM_DIR}/EC-cert.pub \ ${SSH_SOFTHSM_DIR}/RSA.pub \ - ${SSH_SOFTHSM_DIR}/RSA-cert.pub || + ${SSH_SOFTHSM_DIR}/RSA-cert.pub \ + ${SSH_SOFTHSM_DIR}/ED25519.pub \ + ${SSH_SOFTHSM_DIR}/ED25519-cert.pub || fatal "failed to add keys" # Verify their presence +verbose "verify presence" cut -d' ' -f1-2 \ ${SSH_SOFTHSM_DIR}/EC-cert.pub \ - ${SSH_SOFTHSM_DIR}/RSA-cert.pub | sort > $OBJ/expect_list + ${SSH_SOFTHSM_DIR}/RSA-cert.pub \ + ${SSH_SOFTHSM_DIR}/ED25519-cert.pub | sort > $OBJ/expect_list $SSHADD -L | cut -d' ' -f1-2 | sort > $OBJ/output_list diff $OBJ/expect_list $OBJ/output_list # Verify that certs can perform signatures. -for x in ${SSH_SOFTHSM_DIR}/EC-cert.pub ${SSH_SOFTHSM_DIR}/RSA-cert.pub ; do +verbose "check signatures" +for x in ${SSH_SOFTHSM_DIR}/EC-cert.pub ${SSH_SOFTHSM_DIR}/RSA-cert.pub \ + ${SSH_SOFTHSM_DIR}/ED25519-cert.pub ; do $SSHADD -T $x || fail "Signing failed for $x" done diff --git a/regress/agent-pkcs11-restrict.sh b/regress/agent-pkcs11-restrict.sh index 8672532..9fc5e1c 100644 --- a/regress/agent-pkcs11-restrict.sh +++ b/regress/agent-pkcs11-restrict.sh @@ -1,11 +1,11 @@ -# $OpenBSD: agent-pkcs11-restrict.sh,v 1.1 2023/12/18 14:49:39 djm Exp $ +# $OpenBSD: agent-pkcs11-restrict.sh,v 1.3 2025/07/26 01:53:31 djm Exp $ # Placed in the Public Domain. tid="pkcs11 agent constraint test" p11_setup || skip "No PKCS#11 library found" -rm -f $SSH_AUTH_SOCK $OBJ/agent.log $OBJ/host_[abcx]* $OBJ/user_[abcx]* +rm -f $OBJ/host_[abcx]* $OBJ/user_[abcx]* rm -f $OBJ/sshd_proxy_host* $OBJ/ssh_output* $OBJ/expect_* rm -f $OBJ/ssh_proxy[._]* $OBJ/command $OBJ/authorized_keys_* @@ -16,6 +16,7 @@ for h in a b x ca ; do done # XXX test CA hostcerts too. +# XXX test ed25519 keys key_for() { case $h in @@ -26,23 +27,7 @@ key_for() { export K } -SSH_AUTH_SOCK="$OBJ/agent.sock" -export SSH_AUTH_SOCK -rm -f $SSH_AUTH_SOCK -trace "start agent" -${SSHAGENT} ${EXTRA_AGENT_ARGS} -d -a $SSH_AUTH_SOCK > $OBJ/agent.log 2>&1 & -AGENT_PID=$! -trap "kill $AGENT_PID" EXIT -for x in 0 1 2 3 4 ; do - # Give it a chance to start - ${SSHADD} -l > /dev/null 2>&1 - r=$? - test $r -eq 1 && break - sleep 1 -done -if [ $r -ne 1 ]; then - fatal "ssh-add -l did not fail with exit code 1 (got $r)" -fi +start_ssh_agent # XXX a lot of this is a copy of agent-restrict.sh, but I couldn't see a nice # way to factor it out -djm @@ -118,7 +103,7 @@ for h in a b ; do cat $K) >> $OBJ/authorized_keys_$USER done -trace "unrestricted keys" +verbose "unrestricted keys" $SSHADD -qD >/dev/null || fatal "clear agent failed" p11_ssh_add -qs ${TEST_SSH_PKCS11} || fatal "failed to add keys" @@ -134,7 +119,7 @@ for h in a b ; do cmp $OBJ/expect_$h $OBJ/ssh_output || fatal "unexpected output" done -trace "restricted to different host" +verbose "restricted to different host" $SSHADD -qD >/dev/null || fatal "clear agent failed" p11_ssh_add -q -h host_x -s ${TEST_SSH_PKCS11} -H $OBJ/known_hosts || fatal "failed to add keys" @@ -144,7 +129,7 @@ for h in a b ; do host_$h true > $OBJ/ssh_output && fatal "test ssh $h succeeded" done -trace "restricted to destination host" +verbose "restricted to destination host" $SSHADD -qD >/dev/null || fatal "clear agent failed" p11_ssh_add -q -h host_a -h host_b -s ${TEST_SSH_PKCS11} -H $OBJ/known_hosts || fatal "failed to add keys" @@ -160,7 +145,7 @@ for h in a b ; do cmp $OBJ/expect_$h $OBJ/ssh_output || fatal "unexpected output" done -trace "restricted multihop" +verbose "restricted multihop" $SSHADD -qD >/dev/null || fatal "clear agent failed" p11_ssh_add -q -h host_a -h "host_a>host_b" \ -s ${TEST_SSH_PKCS11} -H $OBJ/known_hosts || fatal "failed to add keys" diff --git a/regress/agent-pkcs11.sh b/regress/agent-pkcs11.sh index 304734f..4914666 100644 --- a/regress/agent-pkcs11.sh +++ b/regress/agent-pkcs11.sh @@ -1,54 +1,46 @@ -# $OpenBSD: agent-pkcs11.sh,v 1.13 2023/10/30 23:00:25 djm Exp $ +# $OpenBSD: agent-pkcs11.sh,v 1.15 2025/07/26 01:53:31 djm Exp $ # Placed in the Public Domain. tid="pkcs11 agent test" p11_setup || skip "No PKCS#11 library found" -trace "start agent" -eval `${SSHAGENT} ${EXTRA_AGENT_ARGS} -s` > /dev/null +start_ssh_agent + +trace "add pkcs11 key to agent" +p11_ssh_add -s ${TEST_SSH_PKCS11} > /dev/null 2>&1 r=$? if [ $r -ne 0 ]; then - fail "could not start ssh-agent: exit code $r" -else - trace "add pkcs11 key to agent" - p11_ssh_add -s ${TEST_SSH_PKCS11} > /dev/null 2>&1 - r=$? - if [ $r -ne 0 ]; then - fail "ssh-add -s failed: exit code $r" - fi + fail "ssh-add -s failed: exit code $r" +fi - trace "pkcs11 list via agent" - ${SSHADD} -l > /dev/null 2>&1 - r=$? - if [ $r -ne 0 ]; then - fail "ssh-add -l failed: exit code $r" - fi +trace "pkcs11 list via agent" +${SSHADD} -l > /dev/null 2>&1 +r=$? +if [ $r -ne 0 ]; then + fail "ssh-add -l failed: exit code $r" +fi - for k in $RSA $EC; do - trace "testing $k" - pub=$(cat $k.pub) - ${SSHADD} -L | grep -q "$pub" || \ - fail "key $k missing in ssh-add -L" - ${SSHADD} -T $k.pub || fail "ssh-add -T with $k failed" - - # add to authorized keys - cat $k.pub > $OBJ/authorized_keys_$USER - trace "pkcs11 connect via agent ($k)" - ${SSH} -F $OBJ/ssh_proxy somehost exit 5 - r=$? - if [ $r -ne 5 ]; then - fail "ssh connect failed (exit code $r)" - fi - done - - trace "remove pkcs11 keys" - p11_ssh_add -e ${TEST_SSH_PKCS11} > /dev/null 2>&1 +for k in $ED25519 $RSA $EC; do + trace "testing $k" + pub=$(cat $k.pub) + ${SSHADD} -L | grep -q "$pub" || \ + fail "key $k missing in ssh-add -L" + ${SSHADD} -T $k.pub || fail "ssh-add -T with $k failed" + + # add to authorized keys + cat $k.pub > $OBJ/authorized_keys_$USER + trace "pkcs11 connect via agent ($k)" + ${SSH} -F $OBJ/ssh_proxy somehost exit 5 r=$? - if [ $r -ne 0 ]; then - fail "ssh-add -e failed: exit code $r" + if [ $r -ne 5 ]; then + fail "ssh connect failed (exit code $r)" fi +done - trace "kill agent" - ${SSHAGENT} -k > /dev/null +trace "remove pkcs11 keys" +p11_ssh_add -e ${TEST_SSH_PKCS11} > /dev/null 2>&1 +r=$? +if [ $r -ne 0 ]; then + fail "ssh-add -e failed: exit code $r" fi diff --git a/regress/agent-restrict.sh b/regress/agent-restrict.sh index 62cea85..7fc30fa 100644 --- a/regress/agent-restrict.sh +++ b/regress/agent-restrict.sh @@ -1,4 +1,4 @@ -# $OpenBSD: agent-restrict.sh,v 1.6 2023/03/01 09:29:32 dtucker Exp $ +# $OpenBSD: agent-restrict.sh,v 1.8 2025/05/23 08:40:13 dtucker Exp $ # Placed in the Public Domain. tid="agent restrictions" @@ -39,23 +39,19 @@ Host host_$h Hostname host_$h HostkeyAlias host_$h IdentityFile $OBJ/user_$h - ProxyCommand ${SUDO} env SSH_SK_HELPER=\"$SSH_SK_HELPER\" ${OBJ}/sshd-log-wrapper.sh -i -f $OBJ/sshd_proxy_host_$h + ProxyCommand ${SUDO} env SSH_SK_HELPER=\"$SSH_SK_HELPER\" ${TEST_SSH_SSHD_ENV} ${OBJ}/sshd-log-wrapper.sh -i -f $OBJ/sshd_proxy_host_$h _EOF # Variant with no specified keys. cat << _EOF >> $OBJ/ssh_proxy_noid Host host_$h Hostname host_$h HostkeyAlias host_$h - ProxyCommand ${SUDO} env SSH_SK_HELPER=\"$SSH_SK_HELPER\" ${OBJ}/sshd-log-wrapper.sh -i -f $OBJ/sshd_proxy_host_$h + ProxyCommand ${SUDO} env SSH_SK_HELPER=\"$SSH_SK_HELPER\" ${TEST_SSH_SSHD_ENV} ${OBJ}/sshd-log-wrapper.sh -i -f $OBJ/sshd_proxy_host_$h _EOF done cat $OBJ/ssh_proxy.bak >> $OBJ/ssh_proxy cat $OBJ/ssh_proxy.bak >> $OBJ/ssh_proxy_noid -LC_ALL=C -export LC_ALL -echo "SetEnv LC_ALL=${LC_ALL}" >> sshd_proxy - verbose "prepare known_hosts" rm -f $OBJ/known_hosts for h in a b c x ; do @@ -84,7 +80,8 @@ reset_keys() { _command="" case "$_whichcmd" in authinfo) _command="cat \$SSH_USER_AUTH" ;; - keylist) _command="$SSHADD -L | cut -d' ' -f-2 | sort" ;; + keylist) _command="$SSHADD -L | cut -d' ' -f-2 | \ + env LC_ALL=C sort" ;; *) fatal "unsupported command $_whichcmd" ;; esac trace "reset keys" @@ -227,7 +224,7 @@ rm -f $OBJ/expect_list.pre for u in a b c d e x; do cut -d " " -f-2 $OBJ/user_${u}.pub >> $OBJ/expect_list.pre done -sort $OBJ/expect_list.pre > $OBJ/expect_list +env LC_ALL=C sort $OBJ/expect_list.pre > $OBJ/expect_list for h in a b c d e; do cp $OBJ/expect_list $OBJ/expect_$h expect_succeed $h "unrestricted keylist" @@ -332,7 +329,7 @@ if test ! -z "\$me" ; then cat \$SSH_USER_AUTH fi echo AGENT -$SSHADD -L | egrep "^ssh" | cut -d" " -f-2 | sort +$SSHADD -L | egrep "^ssh" | cut -d" " -f-2 | env LC_ALL=C sort if test -z "\$next" ; then touch $OBJ/done echo "FINISH" @@ -369,7 +366,7 @@ prepare_multihop_expected() { done rm -f $OBJ/expect_a echo "AGENT" >> $OBJ/expect_a - test "x$_keys" = "xnone" || sort $OBJ/expect_keys >> $OBJ/expect_a + test "x$_keys" = "xnone" || env LC_ALL=C sort $OBJ/expect_keys >> $OBJ/expect_a echo "NEXT" >> $OBJ/expect_a for h in $_hops ; do echo "HOSTNAME host_$h" >> $OBJ/expect_a @@ -377,7 +374,7 @@ prepare_multihop_expected() { (printf "publickey " ; cut -d" " -f-2 $OBJ/user_a.pub) >> $OBJ/expect_a echo "AGENT" >> $OBJ/expect_a if test "x$_keys" = "xall" ; then - sort $OBJ/expect_keys >> $OBJ/expect_a + env LC_ALL=C sort $OBJ/expect_keys >> $OBJ/expect_a fi if test "x$h" != "x$_lasthop" ; then if test "x$_keys" = "xfiltered" ; then diff --git a/regress/agent.sh b/regress/agent.sh index 5f10606..26d4c9e 100644 --- a/regress/agent.sh +++ b/regress/agent.sh @@ -1,4 +1,4 @@ -# $OpenBSD: agent.sh,v 1.21 2023/03/01 09:29:32 dtucker Exp $ +# $OpenBSD: agent.sh,v 1.23 2025/05/06 06:05:48 djm Exp $ # Placed in the Public Domain. tid="simple agent test" @@ -86,10 +86,6 @@ fi for t in ${SSH_KEYTYPES}; do trace "connect via agent using $t key" - if [ "$t" = "ssh-dss" ]; then - echo "PubkeyAcceptedAlgorithms +ssh-dss" >> $OBJ/ssh_proxy - echo "PubkeyAcceptedAlgorithms +ssh-dss" >> $OBJ/sshd_proxy - fi ${SSH} -F $OBJ/ssh_proxy -i $OBJ/$t-agent.pub -oIdentitiesOnly=yes \ somehost exit 52 r=$? @@ -143,7 +139,6 @@ fi (printf 'cert-authority,principals="estragon" '; cat $OBJ/user_ca_key.pub) \ > $OBJ/authorized_keys_$USER for t in ${SSH_KEYTYPES}; do - if [ "$t" != "ssh-dss" ]; then trace "connect via agent using $t key" ${SSH} -F $OBJ/ssh_proxy -i $OBJ/$t-agent.pub \ -oCertificateFile=$OBJ/$t-agent-cert.pub \ @@ -152,12 +147,11 @@ for t in ${SSH_KEYTYPES}; do if [ $r -ne 52 ]; then fail "ssh connect with failed (exit code $r)" fi - fi done ## Deletion tests. -trace "delete all agent keys" +trace "delete all agent keys using -D" ${SSHADD} -D > /dev/null 2>&1 r=$? if [ $r -ne 0 ]; then @@ -181,6 +175,29 @@ r=$? if [ $r -ne 0 ]; then fail "ssh-add -l failed: exit code $r" fi +trace "delete all agent keys using SIGUSR1" +kill -s USR1 $SSH_AGENT_PID +r=$? +if [ $r -ne 0 ]; then + fail "kill -s USR1 failed: exit code $r" +fi +# make sure they're gone +${SSHADD} -l > /dev/null 2>&1 +r=$? +if [ $r -ne 1 ]; then + fail "ssh-add -l returned unexpected exit code: $r" +fi +# re-add keys/certs to agent +for t in ${SSH_KEYTYPES}; do + ${SSHADD} $OBJ/$t-agent-private >/dev/null 2>&1 || \ + fail "ssh-add failed exit code $?" +done +# make sure they are there +${SSHADD} -l > /dev/null 2>&1 +r=$? +if [ $r -ne 0 ]; then + fail "ssh-add -l failed: exit code $r" +fi check_key_absent() { ${SSHADD} -L | grep "^$1 " >/dev/null diff --git a/regress/cert-hostkey.sh b/regress/cert-hostkey.sh index a3414e1..0c16077 100644 --- a/regress/cert-hostkey.sh +++ b/regress/cert-hostkey.sh @@ -1,4 +1,4 @@ -# $OpenBSD: cert-hostkey.sh,v 1.27 2021/09/30 05:26:26 dtucker Exp $ +# $OpenBSD: cert-hostkey.sh,v 1.31 2026/02/11 22:58:23 djm Exp $ # Placed in the Public Domain. tid="certified host keys" @@ -70,7 +70,7 @@ touch $OBJ/host_revoked_plain touch $OBJ/host_revoked_cert cat $OBJ/host_ca_key.pub $OBJ/host_ca_key2.pub > $OBJ/host_revoked_ca -PLAIN_TYPES=`echo "$SSH_KEYTYPES" | sed 's/^ssh-dss/ssh-dsa/g;s/^ssh-//'` +PLAIN_TYPES=`echo "$SSH_KEYTYPES" | sed 's/^ssh-//'` if echo "$PLAIN_TYPES" | grep '^rsa$' >/dev/null 2>&1 ; then PLAIN_TYPES="$PLAIN_TYPES rsa-sha2-256 rsa-sha2-512" @@ -143,6 +143,8 @@ for ktype in $PLAIN_TYPES ; do attempt_connect "$ktype basic connect" "yes" attempt_connect "$ktype empty KRL" "yes" \ -oRevokedHostKeys=$OBJ/host_krl_empty + attempt_connect "$ktype multiple KRL files" "no" \ + -oRevokedHostKeys="/dev/null $OBJ/host_krl_plain" attempt_connect "$ktype KRL w/ plain key revoked" "no" \ -oRevokedHostKeys=$OBJ/host_krl_plain attempt_connect "$ktype KRL w/ cert revoked" "no" \ @@ -208,18 +210,32 @@ kh_ca host_ca_key.pub host_ca_key2.pub > $OBJ/known_hosts-cert.orig cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert test_one() { - ident=$1 - result=$2 - sign_opts=$3 + ident="$1" + result="$2" + hosts="$3" + sign_opts="$4" + + test -z "$hosts" || sign_opts="$sign_opts -n $hosts" for kt in $PLAIN_TYPES; do case $ktype in rsa-sha2-*) tflag="-t $ktype"; ca="$OBJ/host_ca_key2" ;; *) tflag=""; ca="$OBJ/host_ca_key" ;; esac - ${SSHKEYGEN} -q -s $ca $tflag -I "regress host key for $USER" \ - $sign_opts $OBJ/cert_host_key_${kt} || - fatal "couldn't sign cert_host_key_${kt}" + if test -z "$hosts" ; then + # Empty principals section. + ${SSHKEYGEN} -q -s $ca $tflag $sign_opts \ + -I "regress host key for $USER" \ + $OBJ/cert_host_key_${kt} 2>/dev/null || + fatal "couldn't sign cert_host_key_${kt}" + else + # Be careful with quoting principals, which may contain + # wilcards. + ${SSHKEYGEN} -q -s $ca $tflag $sign_opts \ + -I "regress host key for $USER" -n "$hosts" \ + $OBJ/cert_host_key_${kt} || + fatal "couldn't sign cert_host_key_${kt}" + fi ( cat $OBJ/sshd_proxy_bak echo HostKey $OBJ/cert_host_key_${kt} @@ -243,13 +259,16 @@ test_one() { done } -test_one "user-certificate" failure "-n $HOSTS" -test_one "empty principals" success "-h" -test_one "wrong principals" failure "-h -n foo" -test_one "cert not yet valid" failure "-h -V20300101:20320101" -test_one "cert expired" failure "-h -V19800101:19900101" -test_one "cert valid interval" success "-h -V-1w:+2w" -test_one "cert has constraints" failure "-h -Oforce-command=false" +test_one "simple" success $HOSTS "-h" +test_one "wildcard" success "loc*" "-h" +test_one "user-certificate" failure $HOSTS +test_one "wildcard user" failure "local*" +test_one "empty principals" failure "" "-h" +test_one "wrong principals" failure foo "-h" +test_one "cert not yet valid" failure $HOSTS "-h -V20300101:20320101" +test_one "cert expired" failure $HOSTS "-h -V19800101:19900101" +test_one "cert valid interval" success $HOSTS "-h -V-1w:+2w" +test_one "cert has constraints" failure $HOSTS "-h -Oforce-command=false" # Check downgrade of cert to raw key when no CA found for ktype in $PLAIN_TYPES ; do diff --git a/regress/cert-userkey.sh b/regress/cert-userkey.sh index 4ea29b7..c0decf0 100644 --- a/regress/cert-userkey.sh +++ b/regress/cert-userkey.sh @@ -1,13 +1,16 @@ -# $OpenBSD: cert-userkey.sh,v 1.28 2021/09/30 05:26:26 dtucker Exp $ +# $OpenBSD: cert-userkey.sh,v 1.32 2026/02/11 22:58:23 djm Exp $ # Placed in the Public Domain. tid="certified user keys" -rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key* -cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak +rm -f $OBJ/authorized_keys_${USER}* $OBJ/user_ca_key* $OBJ/cert_user_key* +rm -f $OBJ/authorized_principals* cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak -PLAIN_TYPES=`$SSH -Q key-plain | maybe_filter_sk | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'` +grep -v AuthorizedKeysFile $OBJ/sshd_proxy > $OBJ/sshd_proxy_bak +echo "AuthorizedKeysFile $OBJ/authorized_keys_%u_*" >> $OBJ/sshd_proxy_bak + +PLAIN_TYPES=`$SSH -Q key-plain | maybe_filter_sk | sed 's/^ssh-//'` EXTRA_TYPES="" rsa="" @@ -22,7 +25,7 @@ kname() { sk-ecdsa-*) n="sk-ecdsa" ;; sk-ssh-ed25519*) n="sk-ssh-ed25519" ;; # subshell because some seds will add a newline - *) n=$(echo $1 | sed 's/^dsa/ssh-dss/;s/^rsa/ssh-rsa/;s/^ed/ssh-ed/') ;; + *) n=$(echo $1 | sed 's/^rsa/ssh-rsa/;s/^ed/ssh-ed/') ;; esac if [ -z "$rsa" ]; then echo "$n*,ssh-ed25519*" @@ -63,11 +66,15 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do _prefix="${ktype}" # Setup for AuthorizedPrincipalsFile - rm -f $OBJ/authorized_keys_$USER + rm -f $OBJ/authorized_keys_${USER}* $OBJ/authorized_principals_${USER}* + touch $OBJ/authorized_keys_${USER}_A + touch $OBJ/authorized_keys_${USER}_Z + touch $OBJ/authorized_principals_${USER}_A + touch $OBJ/authorized_principals_${USER}_Z ( cat $OBJ/sshd_proxy_bak echo "AuthorizedPrincipalsFile " \ - "$OBJ/authorized_principals_%u" + "$OBJ/authorized_principals_%u_*" echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" echo "PubkeyAcceptedAlgorithms ${t}" ) > $OBJ/sshd_proxy @@ -78,7 +85,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do # Missing authorized_principals verbose "$tid: ${_prefix} missing authorized_principals" - rm -f $OBJ/authorized_principals_$USER + rm -f $OBJ/authorized_principals_${USER}_X ${SSH} -i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then @@ -87,7 +94,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do # Empty authorized_principals verbose "$tid: ${_prefix} empty authorized_principals" - echo > $OBJ/authorized_principals_$USER + echo > $OBJ/authorized_principals_${USER}_X ${SSH} -i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then @@ -96,7 +103,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do # Wrong authorized_principals verbose "$tid: ${_prefix} wrong authorized_principals" - echo gregorsamsa > $OBJ/authorized_principals_$USER + echo gregorsamsa > $OBJ/authorized_principals_${USER}_X ${SSH} -i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then @@ -105,7 +112,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do # Correct authorized_principals verbose "$tid: ${_prefix} correct authorized_principals" - echo mekmitasdigoat > $OBJ/authorized_principals_$USER + echo mekmitasdigoat > $OBJ/authorized_principals_${USER}_X ${SSH} -i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -ne 0 ]; then @@ -114,7 +121,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do # authorized_principals with bad key option verbose "$tid: ${_prefix} authorized_principals bad key opt" - echo 'blah mekmitasdigoat' > $OBJ/authorized_principals_$USER + echo 'blah mekmitasdigoat' > $OBJ/authorized_principals_${USER}_X ${SSH} -i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then @@ -124,7 +131,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do # authorized_principals with command=false verbose "$tid: ${_prefix} authorized_principals command=false" echo 'command="false" mekmitasdigoat' > \ - $OBJ/authorized_principals_$USER + $OBJ/authorized_principals_${USER}_X ${SSH} -i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then @@ -135,7 +142,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do # authorized_principals with command=true verbose "$tid: ${_prefix} authorized_principals command=true" echo 'command="true" mekmitasdigoat' > \ - $OBJ/authorized_principals_$USER + $OBJ/authorized_principals_${USER}_X ${SSH} -i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost false >/dev/null 2>&1 if [ $? -ne 0 ]; then @@ -143,7 +150,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do fi # Setup for principals= key option - rm -f $OBJ/authorized_principals_$USER + rm -f $OBJ/authorized_principals_${USER}_X ( cat $OBJ/sshd_proxy_bak echo "PubkeyAcceptedAlgorithms ${t}" @@ -158,7 +165,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do ( printf 'cert-authority,principals="gregorsamsa" ' cat $OBJ/user_ca_key.pub - ) > $OBJ/authorized_keys_$USER + ) > $OBJ/authorized_keys_${USER}_X ${SSH} -i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then @@ -170,7 +177,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do ( printf 'cert-authority,principals="mekmitasdigoat" ' cat $OBJ/user_ca_key.pub - ) > $OBJ/authorized_keys_$USER + ) > $OBJ/authorized_keys_${USER}_X ${SSH} -i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -ne 0 ]; then @@ -180,14 +187,17 @@ done basic_tests() { auth=$1 + rm -f $OBJ/authorized_keys_${USER}* + touch $OBJ/authorized_keys_${USER}_A + touch $OBJ/authorized_keys_${USER}_Z if test "x$auth" = "xauthorized_keys" ; then # Add CA to authorized_keys ( printf 'cert-authority ' cat $OBJ/user_ca_key.pub - ) > $OBJ/authorized_keys_$USER + ) > $OBJ/authorized_keys_${USER}_X else - echo > $OBJ/authorized_keys_$USER + echo > $OBJ/authorized_keys_${USER}_X extra_sshd="TrustedUserCAKeys $OBJ/user_ca_key.pub" fi @@ -216,7 +226,8 @@ basic_tests() { verbose "$tid: ${_prefix} revoked key" ( cat $OBJ/sshd_proxy_bak - echo "RevokedKeys $OBJ/cert_user_key_revoked" + # Also test multiple RevokedKeys files. + echo "RevokedKeys /dev/null $OBJ/cert_user_key_revoked" echo "PubkeyAcceptedAlgorithms ${t}" echo "$extra_sshd" ) > $OBJ/sshd_proxy @@ -295,9 +306,9 @@ test_one() { ( printf "cert-authority${auth_opt} " cat $OBJ/user_ca_key.pub - ) > $OBJ/authorized_keys_$USER + ) > $OBJ/authorized_keys_${USER}_X else - echo > $OBJ/authorized_keys_$USER + echo > $OBJ/authorized_keys_${USER}_X echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" \ >> $OBJ/sshd_proxy echo "PubkeyAcceptedAlgorithms ${t}*" \ @@ -330,31 +341,30 @@ test_one() { } test_one "correct principal" success "-n ${USER}" +test_one "correct principal" success "-n ${USER},*" test_one "host-certificate" failure "-n ${USER} -h" -test_one "wrong principals" failure "-n foo" +test_one "wrong principals" failure "-n foo,*" test_one "cert not yet valid" failure "-n ${USER} -V20300101:20320101" test_one "cert expired" failure "-n ${USER} -V19800101:19900101" test_one "cert valid interval" success "-n ${USER} -V-1w:+2w" test_one "wrong source-address" failure "-n ${USER} -Osource-address=10.0.0.0/8" test_one "force-command" failure "-n ${USER} -Oforce-command=false" - -# Behaviour is different here: TrustedUserCAKeys doesn't allow empty principals -test_one "empty principals" success "" authorized_keys +test_one "empty principals" failure "" authorized_keys test_one "empty principals" failure "" TrustedUserCAKeys # Check explicitly-specified principals: an empty principals list in the cert # should always be refused. # AuthorizedPrincipalsFile -rm -f $OBJ/authorized_keys_$USER -echo mekmitasdigoat > $OBJ/authorized_principals_$USER +rm -f $OBJ/authorized_keys_${USER}_X +echo mekmitasdigoat > $OBJ/authorized_principals_${USER}_X test_one "AuthorizedPrincipalsFile principals" success "-n mekmitasdigoat" \ - TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u" + TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u_*" test_one "AuthorizedPrincipalsFile no principals" failure "" \ - TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u" + TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u_*" # principals= key option -rm -f $OBJ/authorized_principals_$USER +rm -f $OBJ/authorized_principals_${USER}_X test_one "principals key option principals" success "-n mekmitasdigoat" \ authorized_keys ',principals="mekmitasdigoat"' test_one "principals key option no principals" failure "" \ @@ -391,6 +401,6 @@ for ktype in $PLAIN_TYPES ; do fi done -rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key* -rm -f $OBJ/authorized_principals_$USER +rm -f $OBJ/authorized_keys_${USER}* $OBJ/user_ca_key* $OBJ/cert_user_key* +rm -f $OBJ/authorized_principals* diff --git a/regress/cfginclude.sh b/regress/cfginclude.sh index d442cdd..97fd816 100644 --- a/regress/cfginclude.sh +++ b/regress/cfginclude.sh @@ -1,4 +1,4 @@ -# $OpenBSD: cfginclude.sh,v 1.4 2024/09/03 05:58:56 djm Exp $ +# $OpenBSD: cfginclude.sh,v 1.5 2024/09/27 01:05:54 djm Exp $ # Placed in the Public Domain. tid="config include" @@ -10,7 +10,7 @@ cat > $OBJ/ssh_config.i << _EOF Match host a Hostname aa -Match host b # comment +Match host=b # comment Hostname bb Include $OBJ/ssh_config.i.* @@ -18,7 +18,7 @@ Match host c Include $OBJ/ssh_config.i.* Hostname cc -Match host m +Match host=m !user xxxyfake Include $OBJ/ssh_config.i.* # comment Host d @@ -41,7 +41,7 @@ Match host xxxxxx _EOF cat > $OBJ/ssh_config.i.1 << _EOF -Match host a +Match host=a Hostname aaa Match host b @@ -64,10 +64,10 @@ cat > $OBJ/ssh_config.i.2 << _EOF Match host a Hostname aaaa -Match host b +Match host=b !user blahblahfake Hostname bbbb -Match host c +Match host=c Hostname cccc Host d @@ -142,7 +142,7 @@ trial a aa # cleanup rm -f $OBJ/ssh_config.i $OBJ/ssh_config.i.* $OBJ/ssh_config.out -# $OpenBSD: cfginclude.sh,v 1.4 2024/09/03 05:58:56 djm Exp $ +# $OpenBSD: cfginclude.sh,v 1.5 2024/09/27 01:05:54 djm Exp $ # Placed in the Public Domain. tid="config include" diff --git a/regress/cfgmatch.sh b/regress/cfgmatch.sh index 05a6668..d627c37 100644 --- a/regress/cfgmatch.sh +++ b/regress/cfgmatch.sh @@ -1,4 +1,4 @@ -# $OpenBSD: cfgmatch.sh,v 1.13 2021/06/08 06:52:43 djm Exp $ +# $OpenBSD: cfgmatch.sh,v 1.17 2025/12/19 00:57:42 djm Exp $ # Placed in the Public Domain. tid="sshd_config match" @@ -9,6 +9,8 @@ fwd="-L $fwdport:127.0.0.1:$PORT" echo "ExitOnForwardFailure=yes" >> $OBJ/ssh_config echo "ExitOnForwardFailure=yes" >> $OBJ/ssh_proxy +cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak +cp $OBJ/sshd_config $OBJ/sshd_config_bak start_client() { @@ -26,7 +28,7 @@ start_client() kill $client_pid fatal "timeout waiting for background ssh" fi - done + done } stop_client() @@ -38,7 +40,6 @@ stop_client() wait } -cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak echo "PermitOpen 127.0.0.1:1 # comment" >>$OBJ/sshd_config echo "Match Address 127.0.0.1" >>$OBJ/sshd_config echo "PermitOpen 127.0.0.1:2 127.0.0.1:3 127.0.0.1:$PORT" >>$OBJ/sshd_config @@ -106,6 +107,8 @@ cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy echo "PermitOpen 127.0.0.1:1 127.0.0.1:$PORT 127.0.0.2:2" >>$OBJ/sshd_proxy echo "Match User NoSuchUser" >>$OBJ/sshd_proxy echo "PermitOpen 127.0.0.1:1 127.0.0.1:2" >>$OBJ/sshd_proxy +echo "Match Group NoSuchGroup" >>$OBJ/sshd_proxy +echo "PermitOpen 127.0.0.1:1 127.0.0.1:2" >>$OBJ/sshd_proxy # Test that a rule that doesn't match doesn't override, plus test a # PermitOpen entry that's not at the start of the list @@ -119,40 +122,60 @@ stop_client # requires knowledge of actual group memberships user running the test). params="user:user:u1 host:host:h1 address:addr:1.2.3.4 \ localaddress:laddr:5.6.7.8 rdomain:rdomain:rdom1" -cp $OBJ/sshd_proxy_bak $OBJ/sshd_config -echo 'Banner /nomatch' >>$OBJ/sshd_config -for i in $params; do - config=`echo $i | cut -f1 -d:` - criteria=`echo $i | cut -f2 -d:` - value=`echo $i | cut -f3 -d:` - cat >>$OBJ/sshd_config </dev/null || \ + fail "validate config for w/out spec" + + # Test matching each criteria. + for i in $params; do + testcriteria=`echo $i | cut -f2 -d:` + expected=/`echo $i | cut -f3 -d:` + spec="" + for j in $params; do + config=`echo $j | cut -f1 -d:` + criteria=`echo $j | cut -f2 -d:` + value=`echo $j | cut -f3 -d:` + if [ "$criteria" = "$testcriteria" ]; then + spec="$criteria=$value,$spec" + else + spec="$criteria=1$value,$spec" + fi + done + trace "test spec $spec" + result=`${SUDO} ${SSHD} -f $OBJ/sshd_config -T -C "$spec" | \ + awk '$1=="banner"{print $2}'` + if [ "$result" != "$expected" ]; then + fail "match $config expected $expected got $result" fi done - trace "test spec $spec" - result=`${SUDO} ${SSHD} -f $OBJ/sshd_config -T -C "$spec" | \ - awk '$1=="banner"{print $2}'` - if [ "$result" != "$expected" ]; then - fail "match $config expected $expected got $result" - fi done + +# Ensure that invalid subsystems are detected at startup +cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy +cat >> $OBJ/sshd_proxy << _EOF +Match host blah + Subsystem invalid +_EOF +$SSHD -tf $OBJ/sshd_proxy 2>/dev/null && \ + fail "sshd_config accepted invalid subsystem" + +# A single subsystem inside a match block doesn't cause a crash (bz3906) +stop_sshd +grep -vi subsystem $OBJ/sshd_config_bak > $OBJ/sshd_config +echo "Match host *" >> $OBJ/sshd_config +grep -i subsystem $OBJ/sshd_config_bak >> $OBJ/sshd_config +start_sshd +${SSH} -q -F $OBJ/ssh_config somehost true || fatal "ssh failed" + diff --git a/regress/cfgparse.sh b/regress/cfgparse.sh index a9e5c6b..d618e36 100644 --- a/regress/cfgparse.sh +++ b/regress/cfgparse.sh @@ -1,4 +1,4 @@ -# $OpenBSD: cfgparse.sh,v 1.7 2018/05/11 03:51:06 dtucker Exp $ +# $OpenBSD: cfgparse.sh,v 1.9 2025/09/26 04:40:45 dtucker Exp $ # Placed in the Public Domain. tid="sshd config parse" @@ -51,7 +51,7 @@ listenaddress ::1 EOD ($SUDO ${SSHD} -T -f $OBJ/sshd_config.1 | \ - grep 'listenaddress ' >$OBJ/sshd_config.2 && + grep '^listenaddress ' >$OBJ/sshd_config.2 && diff $OBJ/sshd_config.0 $OBJ/sshd_config.2) || \ fail "listenaddress order 1" # test 2: listenaddress first @@ -67,9 +67,22 @@ listenaddress ::1 EOD ($SUDO ${SSHD} -T -f $OBJ/sshd_config.1 | \ - grep 'listenaddress ' >$OBJ/sshd_config.2 && + grep '^listenaddress ' >$OBJ/sshd_config.2 && diff $OBJ/sshd_config.0 $OBJ/sshd_config.2) || \ fail "listenaddress order 2" +# Check idempotence of MaxStartups +verbose "maxstartups idempotent" +echo "maxstartups 1:2:3" > $OBJ/sshd_config.0 +cat > $OBJ/sshd_config.1 <$OBJ/sshd_config.2 && + diff $OBJ/sshd_config.0 $OBJ/sshd_config.2) || \ + fail "maxstartups idempotence" + # cleanup rm -f $OBJ/sshd_config.[012] diff --git a/regress/check-perm.c b/regress/check-perm.c index dac307d..5e5941a 100644 --- a/regress/check-perm.c +++ b/regress/check-perm.c @@ -2,8 +2,6 @@ * Placed in the public domain */ -/* $OpenBSD: modpipe.c,v 1.6 2013/11/21 03:16:47 djm Exp $ */ - #include "includes.h" #include diff --git a/regress/connect-bigconf.sh b/regress/connect-bigconf.sh new file mode 100644 index 0000000..ca2c119 --- /dev/null +++ b/regress/connect-bigconf.sh @@ -0,0 +1,17 @@ +# $OpenBSD: connect-bigconf.sh,v 1.1 2025/07/04 07:52:17 djm Exp $ +# Placed in the Public Domain. + +tid="simple connect" + +for x in `jot 10000 1` ; do + echo "Match version NONEXIST" >> $OBJ/sshd_config + echo "ChrootDirectory /some/path/for/group/NONEXIST" >> $OBJ/sshd_config +done +#cat $OBJ/sshd_config +start_sshd + +trace "direct connect with large sshd_config" +${SSH} -F $OBJ/ssh_config somehost true +if [ $? -ne 0 ]; then + fail "ssh direct connect with large sshd_config failed" +fi diff --git a/regress/dropbear-ciphers.sh b/regress/dropbear-ciphers.sh index 1500fa0..c58cb90 100644 --- a/regress/dropbear-ciphers.sh +++ b/regress/dropbear-ciphers.sh @@ -1,4 +1,4 @@ -# $OpenBSD: dropbear-ciphers.sh,v 1.3 2024/06/20 08:23:18 dtucker Exp $ +# $OpenBSD: dropbear-ciphers.sh,v 1.4 2025/03/11 07:43:03 dtucker Exp $ # Placed in the Public Domain. tid="dropbear ciphers" @@ -26,7 +26,7 @@ for c in $ciphers ; do for kt in $keytype; do verbose "$tid: cipher $c mac $m kt $kt" rm -f ${COPY} - env HOME=$OBJ dbclient -y -i $OBJ/.dropbear/$kt 2>$OBJ/dbclient.log \ + env HOME=$OBJ ${DBCLIENT} -y -i $OBJ/.dropbear/$kt 2>$OBJ/dbclient.log \ -c $c -m $m -J "$OBJ/ssh_proxy.sh" somehost cat ${DATA} > ${COPY} if [ $? -ne 0 ]; then fail "ssh cat $DATA failed" diff --git a/regress/dropbear-kex.sh b/regress/dropbear-kex.sh index d9f1b32..72717fb 100644 --- a/regress/dropbear-kex.sh +++ b/regress/dropbear-kex.sh @@ -1,4 +1,4 @@ -# $OpenBSD: dropbear-kex.sh,v 1.3 2024/06/19 10:10:46 dtucker Exp $ +# $OpenBSD: dropbear-kex.sh,v 1.4 2025/03/11 07:42:08 dtucker Exp $ # Placed in the Public Domain. tid="dropbear kex" @@ -10,8 +10,14 @@ fi cp $OBJ/sshd_proxy $OBJ/sshd_proxy.bak kex="curve25519-sha256 curve25519-sha256@libssh.org" -if $SSH -Q kex | grep 'diffie-hellman-group14-sha1'; then - kex="$kex diffie-hellman-group14-sha256 diffie-hellman-group14-sha1" +if $SSH -Q kex | grep 'diffie-hellman-group14-sha256' >/dev/null; then + kex="$kex diffie-hellman-group14-sha256" +fi +# There's no flag to query KEX, so if MACs does not contain SHA1, assume +# there's also SHA1-based KEX methods either. +if $SSH -Q kex | grep 'diffie-hellman-group14-sha1' >/dev/null && \ + $DBCLIENT -m help hst 2>&1 | grep -- '-sha1' >/dev/null ; then + kex="$kex diffie-hellman-group14-sha1" fi for k in $kex; do @@ -19,8 +25,9 @@ for k in $kex; do rm -f ${COPY} # dbclient doesn't have switch for kex, so force in server (cat $OBJ/sshd_proxy.bak; echo "KexAlgorithms $k") >$OBJ/sshd_proxy - env HOME=$OBJ dbclient -y -i $OBJ/.dropbear/id_ed25519 2>$OBJ/dbclient.log \ - -J "$OBJ/ssh_proxy.sh" somehost cat ${DATA} > ${COPY} + env HOME=$OBJ \ + ${DBCLIENT} -y -i $OBJ/.dropbear/id_ed25519 2>$OBJ/dbclient.log \ + -J "$OBJ/ssh_proxy.sh" somehost cat ${DATA} > ${COPY} if [ $? -ne 0 ]; then fail "ssh cat $DATA failed" fi diff --git a/regress/dropbear-server.sh b/regress/dropbear-server.sh new file mode 100644 index 0000000..c72c86b --- /dev/null +++ b/regress/dropbear-server.sh @@ -0,0 +1,76 @@ +# $OpenBSD: dropbear-server.sh,v 1.2 2025/06/29 05:35:00 dtucker Exp $ +# Placed in the Public Domain. + +tid="dropbear server" + +if test "x$REGRESS_INTEROP_DROPBEAR" != "xyes" ; then + skip "dropbear interop tests not enabled" +fi + +ver="`$DROPBEAR -V 2>&1 | sed 's/Dropbear v//'`" +if [ -z "$ver" ]; then + skip "can't determine dropbear version" +fi + +major=`echo $ver | cut -f1 -d.` +minor=`echo $ver | cut -f2 -d.` + +if [ "$major" -lt "2025" ] || [ "$minor" -lt "87" ]; then + skip "dropbear version $ver (${major}.${minor}) does not support '-D'" +else + trace "dropbear version $ver (${major}.${minor}) ok" +fi + +if [ -z "$SUDO" -a ! -w /var/run ]; then + skip "need SUDO to create dir in /var/run, test won't work without" +fi +authkeydir=/var/run/dropbear-regress + +ciphers=`$DBCLIENT -c help hst 2>&1 | awk '/ ciphers: /{print $4}' | tr ',' ' '` +macs=`$DBCLIENT -m help hst 2>&1 | awk '/ MACs: /{print $4}' | tr ',' ' '` +if [ -z "$macs" ] || [ -z "$ciphers" ]; then + skip "dbclient query ciphers '$ciphers' or macs '$macs' failed" +fi + +# Set up authorized_keys for dropbear. +umask 077 +$SUDO mkdir -p $authkeydir +$SUDO chown -R $USER $authkeydir +cp $OBJ/authorized_keys_$USER $authkeydir/authorized_keys + +for i in `$SUDO $SSHD -f $OBJ/sshd_config -T | grep -v sk- | \ + awk '$1=="hostkey" {print $2}'`; do + file=`basename "$i"` + file=`echo "$file" | sed s/^host\./db\./g` + if $SUDO $DROPBEARCONVERT openssh dropbear "$i" "$OBJ/$file" \ + >/dev/null 2>&1; then + $SUDO chown $USER $OBJ/$file + hkeys="-r $OBJ/$file" + fi +done + +rm -f $OBJ/dropbear.pid +$DROPBEAR -D $authkeydir -p $PORT -P $OBJ/dropbear.pid $hkeys -E \ + 2>$OBJ/sshd.log +if [ $? -ne 0 ]; then + fatal "starting dropbear server failed" +fi +while [ ! -f $OBJ/dropbear.pid ]; do + sleep 1 +done + +pid=`cat $OBJ/dropbear.pid` +trap "kill $pid; $SUDO rm -rf $authkeydir" 0 + +for c in $ciphers; do + for m in $macs; do + trace "$tid: cipher $c mac $m hk $hk" + rm -f ${COPY} + ${SSH} -F $OBJ/ssh_config -oCiphers=$c -oMacs=$m \ + somehost cat ${DATA} > ${COPY} + if [ $? -ne 0 ]; then + fail "connect dropbear server failed" + fi + cmp ${DATA} ${COPY} || fail "corrupted copy" + done +done diff --git a/regress/dsa_ssh2.prv b/regress/dsa_ssh2.prv deleted file mode 100644 index c93b403..0000000 --- a/regress/dsa_ssh2.prv +++ /dev/null @@ -1,14 +0,0 @@ ----- BEGIN SSH2 ENCRYPTED PRIVATE KEY ---- -Subject: ssh-keygen test -Comment: "1024-bit dsa, Tue Jan 08 2002 22:00:23 +0100" -P2/56wAAAgIAAAAmZGwtbW9kcHtzaWdue2RzYS1uaXN0LXNoYTF9LGRoe3BsYWlufX0AAA -AEbm9uZQAAAcQAAAHAAAAAAAAABACwUfm3AxZTut3icBmwCcD48nY64HzuELlQ+vEqjIcR -Lo49es/DQTeLNQ+kdKRCfouosGNv0WqxRtF0tUsWdXxS37oHGa4QPugBdHRd7YlZGZv8kg -x7FsoepY7v7E683/97dv2zxL3AGagTEzWr7fl0yPexAaZoDvtQrrjX44BLmwAABACWQkvv -MxnD8eFkS1konFfMJ1CkuRfTN34CBZ6dY7VTSGemy4QwtFdMKmoufD0eKgy3p5WOeWCYKt -F4FhjHKZk/aaxFjjIbtkrnlvXg64QI11dSZyBN6/ViQkHPSkUDF+A6AAEhrNbQbAFSvao1 -kTvNtPCtL0AkUIduEMzGQfLCTAAAAKDeC043YVo9Zo0zAEeIA4uZh4LBCQAAA/9aj7Y5ik -ehygJ4qTDSlVypsPuV+n59tMS0e2pfrSG87yf5r94AKBmJeho5OO6wYaXCxsVB7AFbSUD6 -75AK8mHF4v1/+7SWKk5f8xlMCMSPZ9K0+j/W1d/q2qkhnnDZolOHDomLA+U00i5ya/jnTV -zyDPWLFpWK8u3xGBPAYX324gAAAKDHFvooRnaXdZbeWGTTqmgHB1GU9A== ----- END SSH2 ENCRYPTED PRIVATE KEY ---- diff --git a/regress/dsa_ssh2.pub b/regress/dsa_ssh2.pub deleted file mode 100644 index 215d73b..0000000 --- a/regress/dsa_ssh2.pub +++ /dev/null @@ -1,13 +0,0 @@ ----- BEGIN SSH2 PUBLIC KEY ---- -Subject: ssh-keygen test -Comment: "1024-bit dsa, Tue Jan 08 2002 22:00:23 +0100" -AAAAB3NzaC1kc3MAAACBALBR+bcDFlO63eJwGbAJwPjydjrgfO4QuVD68SqMhxEujj16z8 -NBN4s1D6R0pEJ+i6iwY2/RarFG0XS1SxZ1fFLfugcZrhA+6AF0dF3tiVkZm/ySDHsWyh6l -ju/sTrzf/3t2/bPEvcAZqBMTNavt+XTI97EBpmgO+1CuuNfjgEubAAAAFQDeC043YVo9Zo -0zAEeIA4uZh4LBCQAAAIEAlkJL7zMZw/HhZEtZKJxXzCdQpLkX0zd+AgWenWO1U0hnpsuE -MLRXTCpqLnw9HioMt6eVjnlgmCrReBYYxymZP2msRY4yG7ZK55b14OuECNdXUmcgTev1Yk -JBz0pFAxfgOgABIazW0GwBUr2qNZE7zbTwrS9AJFCHbhDMxkHywkwAAACAWo+2OYpHocoC -eKkw0pVcqbD7lfp+fbTEtHtqX60hvO8n+a/eACgZiXoaOTjusGGlwsbFQewBW0lA+u+QCv -JhxeL9f/u0lipOX/MZTAjEj2fStPo/1tXf6tqpIZ5w2aJThw6JiwPlNNIucmv4501c8gz1 -ixaVivLt8RgTwGF99uI= ----- END SSH2 PUBLIC KEY ---- diff --git a/regress/dynamic-forward.sh b/regress/dynamic-forward.sh index 85901ea..6cc47e7 100644 --- a/regress/dynamic-forward.sh +++ b/regress/dynamic-forward.sh @@ -1,4 +1,4 @@ -# $OpenBSD: dynamic-forward.sh,v 1.17 2024/03/08 11:34:10 dtucker Exp $ +# $OpenBSD: dynamic-forward.sh,v 1.18 2025/05/21 08:41:52 djm Exp $ # Placed in the Public Domain. tid="dynamic forwarding" @@ -54,7 +54,7 @@ stop_ssh() { check_socks() { direction=$1 expect_success=$2 - for s in 4 5; do + for s in 4A 4 5; do for h in 127.0.0.1 localhost; do trace "testing ssh socks version $s host $h (-$direction)" ${REAL_SSH} -q -F $OBJ/ssh_config -o \ diff --git a/regress/gss-auth.sh b/regress/gss-auth.sh new file mode 100644 index 0000000..c349fbe --- /dev/null +++ b/regress/gss-auth.sh @@ -0,0 +1,196 @@ +tid="GSSAPI Authentication" + +# Skip the test if GSSAPI support is not configured +if ! grep -E '^#define GSSAPI' "$BUILDDIR/config.h" >/dev/null 2>&1; then + skip "GSSAPI not enabled" +fi + +# We test with MIT Kerberos KDC, skip if not installed +if ! which krb5kdc >/dev/null 2>&1; then + skip "MIT Kerberos KDC not installed" +fi + +# The test needs nss_wrapper to emulate gethostname() and /etc/hosts, +# we skip if the shared library is not installed +nss_wrapper="libnss_wrapper.so" +if ! ldconfig -p | grep "$nss_wrapper" >/dev/null 2>&1; then + skip "$nss_wrapper not installed" +fi + +# Set up the username of the SSH client +client="$LOGNAME" +if [ "x$client" = "x" ]; then + client="$(whoami)" +fi + +# Set up SSHD and KDC hostnames and resolve both to localhost +sshd_hostname="sshd.example.org" +bad_hostname="bad.example.org" +kdc_hostname="kdc.example.org" +kdc_port=2088 +hosts="$OBJ/hosts" +echo "127.0.0.1 $sshd_hostname $kdc_hostname" > "$hosts" + +# Set up a directory to store Kerberos data +# (configuration, ticket cache,...) +gssdir="$OBJ/gss" +mkdir -p "$gssdir" +export KRB5CCNAME="$gssdir/cc" +export KRB5_CONFIG="$gssdir/krb5.conf" +export KRB5_KDC_PROFILE="$gssdir/kdc.conf" +export KRB5_KTNAME="$gssdir/ssh.keytab" +export KRB5RCACHETYPE="none" +kdc_pidfile="$gssdir/pid" + +# Configure Kerberos +cat< "$KRB5_KDC_PROFILE" +[realms] + EXAMPLE.ORG = { + database_name = $gssdir/principal + key_stash_file = $gssdir/stash + kdc_listen = $kdc_hostname:$kdc_port + kdc_tcp_listen = $kdc_hostname:$kdc_port + } +[logging] + kdc = FILE:$gssdir/kdc.log + debug = true +EOF + +cat< "$KRB5_CONFIG" +[libdefaults] + default_realm = EXAMPLE.ORG +[realms] + EXAMPLE.ORG = { + kdc = $kdc_hostname:$kdc_port + } +EOF + +# Back up the default sshd_config +cp "$OBJ/sshd_config" "$OBJ/sshd_config.orig" + +setup_sshd() { + mock_hostname="$1" + strict_acceptor="$2" + + cp "$OBJ/sshd_config.orig" "$OBJ/sshd_config" + + cat<> "$OBJ/sshd_config" +PubkeyAuthentication No +PasswordAuthentication No +GSSAPIAuthentication Yes +EOF + + if ! $strict_acceptor; then + echo "GSSAPIStrictAcceptorCheck No" >> "$OBJ/sshd_config" + fi + + test_ssh_sshd_env_backup="$TEST_SSH_SSHD_ENV" + TEST_SSH_SSHD_ENV="$TEST_SSH_SSHD_ENV \ + LD_PRELOAD=$nss_wrapper \ + NSS_WRAPPER_HOSTS=$hosts \ + NSS_WRAPPER_HOSTNAME=$mock_hostname \ + KRB5_CONFIG=$KRB5_CONFIG \ + KRB5_KDC_PROFILE=$KRB5_KDC_PROFILE \ + KRB5CCNAME=$KRB5CCNAME \ + KRB5_KTNAME=$KRB5_KTNAME \ + KRB5RCACHETYPE=$KRB5RCACHETYPE" + start_sshd +} + +teardown_sshd() { + TEST_SSH_SSHD_ENV="$test_ssh_sshd_env_backup" + stop_sshd +} + +setup_kdc() { + kdb5_util create -P "foo" -s + krb5kdc -w 1 -P "$kdc_pidfile" + i=0; + while [ ! -f "$kdc_pidfile" -a $i -lt 10 ]; do + i=$((i + 1)) + sleep 1 + done + test -f "$kdc_pidfile" || fatal "KDC failed to start" +} + +teardown_kdc() { + kill "$(cat "$kdc_pidfile")" + kdestroy + rm -f "$KRB5_KTNAME" "$kdc_pidfile" + kdb5_util destroy -f +} + +setup_nss_emulation() { + export LD_PRELOAD="$nss_wrapper" + export NSS_WRAPPER_HOSTS="$hosts" +} + +teardown_nss_emulation() { + unset LD_PRELOAD + unset NSS_WRAPPER_HOSTS +} + +setup_krb_principal_with_key() { + name="$1" + add_to_keytab="$2" + kadmin.local add_principal -randkey "$name" + if $add_to_keytab; then + kadmin.local ktadd "$name" + fi +} + +setup_krb_principal_with_pw() { + name="$1" + password="$2" + authenticate="$3" + kadmin.local add_principal -pw "$password" "$name" + if $authenticate; then + echo "$password" | kinit "$name" + fi +} + +test_gss_auth() { + sshd_mock_hostname="$1" # the name that gethostname() will return within sshd + sshd_principal="$2" # the hostname for which a Kerberos principal will be created + auth_sshd="$3" # whether sshd will be authenticated via a keytab + auth_client="$4" # whether the client will be authenticated via kinit + strict_acceptor="$5" # whether to be strict about the identity of the sshd server + expect="$6" # the expected return value of the sshd command + + setup_sshd "$sshd_mock_hostname" "$strict_acceptor" + setup_nss_emulation + setup_kdc + + setup_krb_principal_with_key "host/$sshd_principal" "$auth_sshd" + setup_krb_principal_with_pw "$client" "foo" "$auth_client" + + ${SSH} -F "$OBJ/ssh_config" -o "GSSAPIAuthentication Yes" "$client@$sshd_hostname" true + status=$? + + teardown_kdc + teardown_nss_emulation + teardown_sshd + + [ $status -eq $expect ] +} + +# sshd_mock_hostname sshd_principal auth_sshd auth_client strict_acceptor expect +test_gss_auth $sshd_hostname $sshd_hostname true true true 0 \ + || fail "valid authentication attempt failed" +test_gss_auth $sshd_hostname $sshd_hostname false true true 255 \ + || fail "authentication succeeded without a keytab entry for the host" +test_gss_auth $sshd_hostname $sshd_hostname true false true 255 \ + || fail "authentication succeeded without a ticket-granting ticket" +test_gss_auth $bad_hostname $sshd_hostname true true true 255 \ + || fail "authentication succeeded with a hostname/principal mismatch on server side" +test_gss_auth $bad_hostname $sshd_hostname true true false 0 \ + || fail "valid authentication without strict acceptor check failed" +test_gss_auth $bad_hostname $bad_hostname true true true 255 \ + || fail "authentication succeeded with a hostname/principal mismatch on client side" + +unset KRB5CCNAME +unset KRB5_CONFIG +unset KRB5_KDC_PROFILE +unset KRB5_KTNAME +unset KRB5RCACHETYPE +rm -r "$gssdir" diff --git a/regress/hostbased.sh b/regress/hostbased.sh index eb9cf27..69808ce 100644 --- a/regress/hostbased.sh +++ b/regress/hostbased.sh @@ -1,8 +1,8 @@ -# $OpenBSD: hostbased.sh,v 1.4 2022/12/07 11:45:43 dtucker Exp $ +# $OpenBSD: hostbased.sh,v 1.9 2026/03/24 12:31:35 dtucker Exp $ # Placed in the Public Domain. # This test requires external setup and thus is skipped unless -# TEST_SSH_HOSTBASED_AUTH and SUDO are set to "yes". +# TEST_SSH_HOSTBASED_AUTH and SUDO are set. # Since ssh-keysign has key paths hard coded, unlike the other tests it # needs to use the real host keys. It requires: # - ssh-keysign must be installed and setuid. @@ -10,12 +10,34 @@ # - the system's own real FQDN the system-wide shosts.equiv. # - the system's real public key fingerprints must be in global ssh_known_hosts. # +# Setting TEST_SSH_HOSTBASED_AUTH to the special value "setupandrun" will, +# if run with SUDO, perform this setup and run the test. Note that this will +# MODIFY THE SYSTEM'S GLOBAL CONFIG to enable HostbasedAuthentication and +# leave it enabled, so do not do this on a system that matters. +# tid="hostbased" if [ -z "${TEST_SSH_HOSTBASED_AUTH}" ]; then skip "TEST_SSH_HOSTBASED_AUTH not set." elif [ -z "${SUDO}" ]; then skip "SUDO not set" +elif [ "${TEST_SSH_HOSTBASED_AUTH}" = "setupandrun" ]; then + verbose "setting up system for hostbased auth" + knownhosts=`$SSH -G localhost | \ + awk '$1=="globalknownhostsfile" {print $2}'` + sshconf=`dirname $knownhosts` + hostname >~/.shosts + if ! grep "^EnableSSHKeysign yes" $sshconf/ssh_config >/dev/null; then + echo "EnableSSHKeysign yes" | \ + $SUDO tee -a $sshconf/ssh_config >/dev/null + fi + $SUDO touch "$knownhosts" + for pubkey in $sshconf/ssh_host*key*.pub; do + line="`hostname` `cat $pubkey`" + if ! grep "$line" "$knownhosts" >/dev/null; then + echo "$line" | $SUDO tee -a $knownhosts >/dev/null + fi + done fi # Enable all supported hostkey algos (but no others) @@ -25,6 +47,7 @@ cat >>$OBJ/sshd_proxy < $OBJ/ssh_proxy +echo "UpdateHostkeys=yes" >> $OBJ/ssh_proxy +echo "GlobalKnownHostsFile=none" >> $OBJ/ssh_proxy + +for k in $SSH_KEYTYPES ; do + verbose "Addkey type $k" + echo "Hostkey $OBJ/agent-key.${k}" >> $OBJ/sshd_proxy + + ( printf 'localhost-with-alias ' ; + cat $OBJ/agent-key.$k.pub) > $OBJ/known_hosts +done + +opts="-oStrictHostKeyChecking=yes -F $OBJ/ssh_proxy" +SSH_CONNECTION=`${SSH} $opts host 'echo $SSH_CONNECTION'` +if [ $? -ne 0 ]; then + fail "connection to server with multiple hostkeys failed" +fi +if [ "$SSH_CONNECTION" != "UNKNOWN 65535 UNKNOWN 65535" ]; then + fail "bad SSH_CONNECTION key while using multiple hostkeys" +fi + trace "kill agent" ${SSHAGENT} -k > /dev/null diff --git a/regress/kbdint.sh b/regress/kbdint.sh new file mode 100644 index 0000000..7db8761 --- /dev/null +++ b/regress/kbdint.sh @@ -0,0 +1,86 @@ +# $OpenBSD: kbdint.sh,v 1.2 2026/02/24 00:39:59 dtucker Exp $ +# Placed in the Public Domain. +# +# This tests keyboard-interactive authentication. It does not run by default, +# and needs to be enabled by putting the password of the user running the tests +# into ${OBJ}/kbdintpw. Since this obviously puts the password at risk it is +# recommended to do this on a throwaway VM by setting a random password +# (and randomizing it again after the test, if you can't immediately dispose +# of the VM). + +tid="kbdint" + +if [ -z "$SUDO" -o ! -f ${OBJ}/kbdintpw ]; then + skip "Password auth requires SUDO and kbdintpw file." +fi + +# Enable keyboard-interactive auth +echo "KbdInteractiveAuthentication yes" >>sshd_proxy + +# Create askpass script to replay a series of password responses. +# Keep a counter of the number of times it has been called and +# reply with the next line of the replypass file. +cat >${OBJ}/replypass.sh <${OBJ}/replypass.N +EOD +chmod 700 ${OBJ}/replypass.sh + +SSH_ASKPASS=${OBJ}/replypass.sh +SSH_ASKPASS_REQUIRE=force +export SSH_ASKPASS SSH_ASKPASS_REQUIRE + +opts="-oKbdInteractiveAuthentication=yes -oPreferredAuthentications=keyboard-interactive" +opts="-oBatchMode=no $opts" + +trace correct password 1st attempt +cat ${OBJ}/kbdintpw >${OBJ}/replypass +echo 1 >${OBJ}/replypass.N +${SSH} $opts -F $OBJ/ssh_proxy somehost true +if [ $? -ne 0 ]; then + fail "ssh kdbint failed" +fi + +trace bad password +echo badpass >${OBJ}/replypass +echo 1 >${OBJ}/replypass.N +${SSH} $opts -F $OBJ/ssh_proxy somehost true +if [ $? -eq 0 ]; then + fail "ssh unexpectedly succeeded" +fi + +trace correct password 2nd attempt +(echo badpass; cat ${OBJ}/kbdintpw) >${OBJ}/replypass +echo 1 >${OBJ}/replypass.N +${SSH} $opts -F $OBJ/ssh_proxy somehost true +if [ $? -ne 0 ]; then + fail "did not succeed on 2nd attempt" +fi + +trace empty password +echo >${OBJ}/replypass +echo 1 >${OBJ}/replypass.N +${SSH} $opts -F $OBJ/ssh_proxy somehost true +if [ $? -eq 0 ]; then + fail "ssh unexpectedly succeeded with empty password" +fi + +trace huge password +(for i in 0 1 2 3 4 5 6 7 8 9; do printf 0123456789; done; echo) \ + >${OBJ}/replypass +echo 1 >${OBJ}/replypass.N +${SSH} $opts -F $OBJ/ssh_proxy somehost true +if [ $? -eq 0 ]; then + fail "ssh unexpectedly succeeded with huge password" +fi + +trace spam password +for i in 0 1 2 3 4 5 6 7 8 9; do printf '1\n2\n3\n4\n5\n6\n7\n8\n9\n'; done \ + >${OBJ}/replypass +echo 1 >${OBJ}/replypass.N +${SSH} $opts -F $OBJ/ssh_proxy somehost true +if [ $? -eq 0 ]; then + fail "ssh unexpectedly succeeded with password spam" +fi diff --git a/regress/key-options.sh b/regress/key-options.sh index 623128c..7f9b45f 100644 --- a/regress/key-options.sh +++ b/regress/key-options.sh @@ -1,4 +1,4 @@ -# $OpenBSD: key-options.sh,v 1.10 2024/03/25 02:07:08 dtucker Exp $ +# $OpenBSD: key-options.sh,v 1.11 2024/12/05 14:28:39 dtucker Exp $ # Placed in the Public Domain. tid="key options" @@ -120,5 +120,8 @@ check_valid_before() { check_valid_before "default" "" "pass" check_valid_before "invalid" 'expiry-time="INVALID"' "fail" check_valid_before "expired" 'expiry-time="19990101"' "fail" +if config_defined "SIZEOF_TIME_T 4"; then check_valid_before "valid" 'expiry-time="20380101"' "pass" - +else +check_valid_before "valid-64b" 'expiry-time="25250101"' "pass" +fi diff --git a/regress/keygen-comment.sh b/regress/keygen-comment.sh index af571d3..56dde0e 100644 --- a/regress/keygen-comment.sh +++ b/regress/keygen-comment.sh @@ -1,4 +1,5 @@ -#    Placed in the Public Domain. +# $OpenBSD: keygen-comment.sh,v 1.3 2025/10/01 00:30:19 dtucker Exp $ +# Placed in the Public Domain. tid="Comment extraction from private key" diff --git a/regress/keytype.sh b/regress/keytype.sh index f1c0451..11ef7d0 100644 --- a/regress/keytype.sh +++ b/regress/keytype.sh @@ -1,4 +1,4 @@ -# $OpenBSD: keytype.sh,v 1.11 2021/02/25 03:27:34 djm Exp $ +# $OpenBSD: keytype.sh,v 1.12 2025/05/06 06:05:48 djm Exp $ # Placed in the Public Domain. tid="login with different key types" @@ -10,7 +10,6 @@ cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak ktypes="" for i in ${SSH_KEYTYPES}; do case "$i" in - ssh-dss) ktypes="$ktypes dsa-1024" ;; ssh-rsa) ktypes="$ktypes rsa-2048 rsa-3072" ;; ssh-ed25519) ktypes="$ktypes ed25519-512" ;; ecdsa-sha2-nistp256) ktypes="$ktypes ecdsa-256" ;; @@ -36,7 +35,6 @@ done kname_to_ktype() { case $1 in - dsa-1024) echo ssh-dss;; ecdsa-256) echo ecdsa-sha2-nistp256;; ecdsa-384) echo ecdsa-sha2-nistp384;; ecdsa-521) echo ecdsa-sha2-nistp521;; diff --git a/regress/knownhosts-command.sh b/regress/knownhosts-command.sh index 8472ec8..2ed6fa0 100644 --- a/regress/knownhosts-command.sh +++ b/regress/knownhosts-command.sh @@ -1,4 +1,4 @@ -# $OpenBSD: knownhosts-command.sh,v 1.3 2021/08/30 01:15:45 djm Exp $ +# $OpenBSD: knownhosts-command.sh,v 1.4 2025/05/06 06:05:48 djm Exp $ # Placed in the Public Domain. tid="known hosts command " @@ -40,7 +40,6 @@ ${SSH} -F $OBJ/ssh_proxy x true && fail "ssh connect succeeded with bad exit" for keytype in ${SSH_HOSTKEY_TYPES} ; do algs=$keytype - test "x$keytype" = "xssh-dss" && continue test "x$keytype" = "xssh-rsa" && algs=ssh-rsa,rsa-sha2-256,rsa-sha2-512 verbose "keytype $keytype" cat > $OBJ/knownhosts_command << _EOF diff --git a/regress/krl.sh b/regress/krl.sh index d560d61..37d9f17 100644 --- a/regress/krl.sh +++ b/regress/krl.sh @@ -1,4 +1,4 @@ -# $OpenBSD: krl.sh,v 1.12 2023/01/16 04:11:29 djm Exp $ +# $OpenBSD: krl.sh,v 1.13 2025/05/06 06:05:48 djm Exp $ # Placed in the Public Domain. tid="key revocation lists" @@ -11,7 +11,6 @@ for t in $SSH_KEYTYPES; do case "$t" in ecdsa*) ktype2=ecdsa ;; ssh-rsa) ktype3=rsa ;; - ssh-dss) ktype4=dsa ;; sk-ssh-ed25519@openssh.com) ktype5=ed25519-sk ;; sk-ecdsa-sha2-nistp256@openssh.com) ktype6=ecdsa-sk ;; esac diff --git a/regress/limit-keytype.sh b/regress/limit-keytype.sh index 7127de0..2f5b63a 100644 --- a/regress/limit-keytype.sh +++ b/regress/limit-keytype.sh @@ -1,4 +1,4 @@ -# $OpenBSD: limit-keytype.sh,v 1.10 2021/02/25 03:27:34 djm Exp $ +# $OpenBSD: limit-keytype.sh,v 1.11 2025/05/06 06:05:48 djm Exp $ # Placed in the Public Domain. tid="restrict pubkey type" @@ -17,7 +17,6 @@ for t in $SSH_KEYTYPES ; do case "$t" in ssh-rsa) ktype2=rsa ;; ecdsa*) ktype3=ecdsa ;; # unused - ssh-dss) ktype4=dsa ;; sk-ssh-ed25519@openssh.com) ktype5=ed25519-sk ;; sk-ecdsa-sha2-nistp256@openssh.com) ktype6=ecdsa-sk ;; esac @@ -75,7 +74,6 @@ keytype() { case "$1" in ecdsa) printf "ecdsa-sha2-*" ;; ed25519) printf "ssh-ed25519" ;; - dsa) printf "ssh-dss" ;; rsa) printf "rsa-sha2-256,rsa-sha2-512,ssh-rsa" ;; sk-ecdsa) printf "sk-ecdsa-*" ;; sk-ssh-ed25519) printf "sk-ssh-ed25519-*" ;; @@ -123,7 +121,7 @@ if [ "$ktype1" != "$ktype2" ]; then fi ${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed" -# Allow only DSA in main config, Ed25519 for user. +# Allow only Ed25519 in main config, Ed25519 for user. verbose "match w/ matching" prepare_config "PubkeyAcceptedAlgorithms `keytype $ktype4`" \ "Match user $USER" "PubkeyAcceptedAlgorithms +`keytype $ktype1`" diff --git a/regress/misc/fuzz-harness/Makefile b/regress/misc/fuzz-harness/Makefile index 55dcc17..2963ba6 100644 --- a/regress/misc/fuzz-harness/Makefile +++ b/regress/misc/fuzz-harness/Makefile @@ -1,15 +1,16 @@ # NB. libssh and libopenbsd-compat should be built with the same sanitizer opts. -CC=clang-16 -CXX=clang++-16 +CC=clang-19 +CXX=clang++-19 FUZZ_FLAGS=-fsanitize=address,fuzzer -fno-omit-frame-pointer -FUZZ_LIBS=-L/usr/lib/llvm-16/lib -lFuzzer +FUZZ_LIBS=-L/usr/lib/llvm-19/lib -lFuzzer CFLAGS=-D_GNU_SOURCE=1 -O2 -g -Wall -Wextra -Wno-unused-parameter -Wno-exceptions -Wno-deprecated -I ../../.. CXXFLAGS=$(CFLAGS) $(FUZZ_FLAGS) LDFLAGS=-L ../../.. -L ../../../openbsd-compat -g -LIBS=-lssh -lopenbsd-compat -lmd -lcrypto -lfido2 -lcbor $(FUZZ_LIBS) +COMMON_OBJS=../../../ssh-pkcs11-client.o +LIBS=$(COMMON_OBJS) -lssh -lopenbsd-compat -lmd -lcrypto -lfido2 -lcbor $(FUZZ_LIBS) SK_NULL_OBJS=ssh-sk-null.o -COMMON_DEPS=../../../libssh.a +COMMON_DEPS=../../../libssh.a $(COMMON_OBJS) TARGETS=pubkey_fuzz sig_fuzz authopt_fuzz authkeys_fuzz sshsig_fuzz \ sshsigopt_fuzz privkey_fuzz kex_fuzz agent_fuzz \ diff --git a/regress/misc/fuzz-harness/agent_fuzz_helper.c b/regress/misc/fuzz-harness/agent_fuzz_helper.c index 321343b..400b631 100644 --- a/regress/misc/fuzz-harness/agent_fuzz_helper.c +++ b/regress/misc/fuzz-harness/agent_fuzz_helper.c @@ -158,6 +158,7 @@ test_one(const uint8_t* s, size_t slen) SYSLOG_FACILITY_AUTH, 1); devnull = devnull_or_die(); allowed_providers = xstrdup(""); + websafe_allowlist = xstrdup("*"); setenv("DISPLAY", "", 1); /* ban askpass */ } @@ -174,10 +175,3 @@ test_one(const uint8_t* s, size_t slen) cleanup_idtab(); cleanup_sockettab(); } - -int -pkcs11_make_cert(const struct sshkey *priv, - const struct sshkey *certpub, struct sshkey **certprivp) -{ - return -1; /* XXX */ -} diff --git a/regress/misc/fuzz-harness/fixed-keys.h b/regress/misc/fuzz-harness/fixed-keys.h index c6e7c6c..61afa87 100644 --- a/regress/misc/fuzz-harness/fixed-keys.h +++ b/regress/misc/fuzz-harness/fixed-keys.h @@ -34,32 +34,6 @@ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDf56l/5UYqgY9oBlet/pLRzK6ZCd12QYGdUVfQDl6HftG0u6DSpjm2HGwFRsYZWv2ZN3ZBfAu6MHBiDmXUw/8WaD7nfXZmDH2keZL6opQttqvSGU2Cm00Rv5o1R3ej2qDdpepebv5meMBXTl5/+bE1E3Zm+4STDtxGmlMlxsEj68XeVe4JedfaSUMj3kaXYBbdYdG1qeosdle4GSONEEMpzsxSr8Y/WGYuIB33l29Tt9mNGUgSw/zjMYQjUVvQv+SY8dw62JV8d+3wK2YL2/r73gms6I8EE1JxX53KuAAY+x0p2v/W8ilCYI2Ijyzc8KIPwntmIFpibQjx+rkb+qdT" #define CERT_RSA \ "ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAg89JX6OBMYDSxER8fnU5y8xxeMCHR/hI0uVqdEhNyCpcAAAADAQABAAABAQDf56l/5UYqgY9oBlet/pLRzK6ZCd12QYGdUVfQDl6HftG0u6DSpjm2HGwFRsYZWv2ZN3ZBfAu6MHBiDmXUw/8WaD7nfXZmDH2keZL6opQttqvSGU2Cm00Rv5o1R3ej2qDdpepebv5meMBXTl5/+bE1E3Zm+4STDtxGmlMlxsEj68XeVe4JedfaSUMj3kaXYBbdYdG1qeosdle4GSONEEMpzsxSr8Y/WGYuIB33l29Tt9mNGUgSw/zjMYQjUVvQv+SY8dw62JV8d+3wK2YL2/r73gms6I8EE1JxX53KuAAY+x0p2v/W8ilCYI2Ijyzc8KIPwntmIFpibQjx+rkb+qdTAAAAAAAAA+0AAAABAAAAB3VseXNzZXMAAAAXAAAAB3VseXNzZXMAAAAIb2R5c3NldXMAAAAAAAAAAP//////////AAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAADMAAAALc3NoLWVkMjU1MTkAAAAgM9BeYRUxUuZ4VHJp8oxVaA8OS/z+5EFPCZwQNq1nMwMAAABTAAAAC3NzaC1lZDI1NTE5AAAAQGCDA6PWw4x9bHQl0w7NqifHepumqD3dmyMx+hZGuPRon+TsyCjfytu7hWmV7l9XUF0fPQNFQ7FGat5e+7YUNgE= id_rsa.pub" -#define PRIV_DSA \ -"-----BEGIN OPENSSH PRIVATE KEY-----\n"\ -"b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABsgAAAAdzc2gtZH\n"\ -"NzAAAAgQCsGTfjpQ465EOkfQXJM9BOvfRQE0fqlykAls+ncz+T7hrbeScRu8xpwzsznJNm\n"\ -"xlW8o6cUDiHmBJ5OHgamUC9N7YJeU/6fnOAZifgN8mqK6k8pKHuje8ANOiYgHLl0yiASQA\n"\ -"3//qMyzZ+W/hemoLSmLAbEqlfWVeyYx+wta1Vm+QAAABUAvWyehvUvdHvQxavYgS5p0t5Q\n"\ -"d7UAAACBAIRA9Yy+f4Kzqpv/qICPO3zk42UuP7WAhSW2nCbQdLlCiSTxcjKgcvXNRckwJP\n"\ -"44JjSHOtJy/AMtJrPIbLYG6KuWTdBlEHFiG6DafvLG+qPMSL2bPjXTOhuOMbCHIZ+5WBkW\n"\ -"THeG/Nv11iI01Of9V6tXkig23K370flkRkXFi9MdAAAAgCt6YUcQkNwG7B/e5M1FZsLP9O\n"\ -"kVB3BwLAOjmWdHpyhu3HpwSJa3XLEvhXN0i6IVI2KgPo/2GtYA6rHt14L+6u1pmhh8sAvQ\n"\ -"ksp3qZB+xh/NP+hBqf0sbHX0yYbzKOvI5SCc/kKK6yagcBZOsubM/KC8TxyVgmD5c6WzYs\n"\ -"h5TEpvAAAB2PHjRbbx40W2AAAAB3NzaC1kc3MAAACBAKwZN+OlDjrkQ6R9Bckz0E699FAT\n"\ -"R+qXKQCWz6dzP5PuGtt5JxG7zGnDOzOck2bGVbyjpxQOIeYEnk4eBqZQL03tgl5T/p+c4B\n"\ -"mJ+A3yaorqTykoe6N7wA06JiAcuXTKIBJADf/+ozLNn5b+F6agtKYsBsSqV9ZV7JjH7C1r\n"\ -"VWb5AAAAFQC9bJ6G9S90e9DFq9iBLmnS3lB3tQAAAIEAhED1jL5/grOqm/+ogI87fOTjZS\n"\ -"4/tYCFJbacJtB0uUKJJPFyMqBy9c1FyTAk/jgmNIc60nL8Ay0ms8hstgboq5ZN0GUQcWIb\n"\ -"oNp+8sb6o8xIvZs+NdM6G44xsIchn7lYGRZMd4b82/XWIjTU5/1Xq1eSKDbcrfvR+WRGRc\n"\ -"WL0x0AAACAK3phRxCQ3AbsH97kzUVmws/06RUHcHAsA6OZZ0enKG7cenBIlrdcsS+Fc3SL\n"\ -"ohUjYqA+j/Ya1gDqse3Xgv7q7WmaGHywC9CSynepkH7GH80/6EGp/SxsdfTJhvMo68jlIJ\n"\ -"z+QorrJqBwFk6y5sz8oLxPHJWCYPlzpbNiyHlMSm8AAAAUUA+OGldMi76ClO/sstpdbBUE\n"\ -"lq8AAAAAAQI=\n"\ -"-----END OPENSSH PRIVATE KEY-----\n" -#define PUB_DSA \ -"ssh-dss AAAAB3NzaC1kc3MAAACBAKwZN+OlDjrkQ6R9Bckz0E699FATR+qXKQCWz6dzP5PuGtt5JxG7zGnDOzOck2bGVbyjpxQOIeYEnk4eBqZQL03tgl5T/p+c4BmJ+A3yaorqTykoe6N7wA06JiAcuXTKIBJADf/+ozLNn5b+F6agtKYsBsSqV9ZV7JjH7C1rVWb5AAAAFQC9bJ6G9S90e9DFq9iBLmnS3lB3tQAAAIEAhED1jL5/grOqm/+ogI87fOTjZS4/tYCFJbacJtB0uUKJJPFyMqBy9c1FyTAk/jgmNIc60nL8Ay0ms8hstgboq5ZN0GUQcWIboNp+8sb6o8xIvZs+NdM6G44xsIchn7lYGRZMd4b82/XWIjTU5/1Xq1eSKDbcrfvR+WRGRcWL0x0AAACAK3phRxCQ3AbsH97kzUVmws/06RUHcHAsA6OZZ0enKG7cenBIlrdcsS+Fc3SLohUjYqA+j/Ya1gDqse3Xgv7q7WmaGHywC9CSynepkH7GH80/6EGp/SxsdfTJhvMo68jlIJz+QorrJqBwFk6y5sz8oLxPHJWCYPlzpbNiyHlMSm8=" -#define CERT_DSA \ -"ssh-dss-cert-v01@openssh.com AAAAHHNzaC1kc3MtY2VydC12MDFAb3BlbnNzaC5jb20AAAAguF716Yub+vVKNlONKLsfxGYWkRe/PyjfYdGRTsFaDvAAAACBAKwZN+OlDjrkQ6R9Bckz0E699FATR+qXKQCWz6dzP5PuGtt5JxG7zGnDOzOck2bGVbyjpxQOIeYEnk4eBqZQL03tgl5T/p+c4BmJ+A3yaorqTykoe6N7wA06JiAcuXTKIBJADf/+ozLNn5b+F6agtKYsBsSqV9ZV7JjH7C1rVWb5AAAAFQC9bJ6G9S90e9DFq9iBLmnS3lB3tQAAAIEAhED1jL5/grOqm/+ogI87fOTjZS4/tYCFJbacJtB0uUKJJPFyMqBy9c1FyTAk/jgmNIc60nL8Ay0ms8hstgboq5ZN0GUQcWIboNp+8sb6o8xIvZs+NdM6G44xsIchn7lYGRZMd4b82/XWIjTU5/1Xq1eSKDbcrfvR+WRGRcWL0x0AAACAK3phRxCQ3AbsH97kzUVmws/06RUHcHAsA6OZZ0enKG7cenBIlrdcsS+Fc3SLohUjYqA+j/Ya1gDqse3Xgv7q7WmaGHywC9CSynepkH7GH80/6EGp/SxsdfTJhvMo68jlIJz+QorrJqBwFk6y5sz8oLxPHJWCYPlzpbNiyHlMSm8AAAAAAAAD6AAAAAEAAAAHdWx5c3NlcwAAABcAAAAHdWx5c3NlcwAAAAhvZHlzc2V1cwAAAAAAAAAA//////////8AAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACAz0F5hFTFS5nhUcmnyjFVoDw5L/P7kQU8JnBA2rWczAwAAAFMAAAALc3NoLWVkMjU1MTkAAABAjMQEZcbdUYJBjIC4GxByFDOb8tv71vDZdx7irHwaqIjx5rzpJUuOV1r8ZO4kY+Yaiun1yrWj2QYkfJrHBvD1DA== id_dsa.pub" #define PRIV_ECDSA \ "-----BEGIN OPENSSH PRIVATE KEY-----\n"\ "b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAaAAAABNlY2RzYS\n"\ diff --git a/regress/misc/fuzz-harness/testdata/create-agent-corpus.sh b/regress/misc/fuzz-harness/testdata/create-agent-corpus.sh index 1043b9f..842b8c4 100755 --- a/regress/misc/fuzz-harness/testdata/create-agent-corpus.sh +++ b/regress/misc/fuzz-harness/testdata/create-agent-corpus.sh @@ -14,7 +14,7 @@ sleep 1 AGENT_PID=$! trap "kill $AGENT_PID" EXIT -PRIV="id_dsa id_ecdsa id_ecdsa_sk id_ed25519 id_ed25519_sk id_rsa" +PRIV="id_ecdsa id_ecdsa_sk id_ed25519 id_ed25519_sk id_rsa" # add keys ssh-add $PRIV diff --git a/regress/misc/fuzz-harness/testdata/id_dsa-cert.pub b/regress/misc/fuzz-harness/testdata/id_dsa-cert.pub deleted file mode 100644 index 3afb87f..0000000 --- a/regress/misc/fuzz-harness/testdata/id_dsa-cert.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-dss-cert-v01@openssh.com AAAAHHNzaC1kc3MtY2VydC12MDFAb3BlbnNzaC5jb20AAAAguF716Yub+vVKNlONKLsfxGYWkRe/PyjfYdGRTsFaDvAAAACBAKwZN+OlDjrkQ6R9Bckz0E699FATR+qXKQCWz6dzP5PuGtt5JxG7zGnDOzOck2bGVbyjpxQOIeYEnk4eBqZQL03tgl5T/p+c4BmJ+A3yaorqTykoe6N7wA06JiAcuXTKIBJADf/+ozLNn5b+F6agtKYsBsSqV9ZV7JjH7C1rVWb5AAAAFQC9bJ6G9S90e9DFq9iBLmnS3lB3tQAAAIEAhED1jL5/grOqm/+ogI87fOTjZS4/tYCFJbacJtB0uUKJJPFyMqBy9c1FyTAk/jgmNIc60nL8Ay0ms8hstgboq5ZN0GUQcWIboNp+8sb6o8xIvZs+NdM6G44xsIchn7lYGRZMd4b82/XWIjTU5/1Xq1eSKDbcrfvR+WRGRcWL0x0AAACAK3phRxCQ3AbsH97kzUVmws/06RUHcHAsA6OZZ0enKG7cenBIlrdcsS+Fc3SLohUjYqA+j/Ya1gDqse3Xgv7q7WmaGHywC9CSynepkH7GH80/6EGp/SxsdfTJhvMo68jlIJz+QorrJqBwFk6y5sz8oLxPHJWCYPlzpbNiyHlMSm8AAAAAAAAD6AAAAAEAAAAHdWx5c3NlcwAAABcAAAAHdWx5c3NlcwAAAAhvZHlzc2V1cwAAAAAAAAAA//////////8AAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACAz0F5hFTFS5nhUcmnyjFVoDw5L/P7kQU8JnBA2rWczAwAAAFMAAAALc3NoLWVkMjU1MTkAAABAjMQEZcbdUYJBjIC4GxByFDOb8tv71vDZdx7irHwaqIjx5rzpJUuOV1r8ZO4kY+Yaiun1yrWj2QYkfJrHBvD1DA== id_dsa.pub diff --git a/regress/misc/sk-dummy/Makefile b/regress/misc/sk-dummy/Makefile index 18b0a24..2a88617 100644 --- a/regress/misc/sk-dummy/Makefile +++ b/regress/misc/sk-dummy/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.3 2023/01/15 23:35:10 djm Exp $ +# $OpenBSD: Makefile,v 1.7 2025/11/06 17:24:28 djm Exp $ .include .include @@ -9,9 +9,10 @@ NOMAN= SSHREL=../../../../../usr.bin/ssh .PATH: ${.CURDIR}/${SSHREL} -SRCS=sk-dummy.c +SRCS=sk-dummy.c fatal.c # From usr.bin/ssh -SRCS+=ed25519.c hash.c +SRCS+=ed25519-openssl.c +#SRCS+=ed25519.c OPENSSL?= yes CFLAGS+= -fPIC @@ -36,6 +37,7 @@ CDIAGFLAGS+= -Wimplicit CDIAGFLAGS+= -Winline CDIAGFLAGS+= -Wmissing-declarations CDIAGFLAGS+= -Wmissing-prototypes +CDIAGFLAGS+= -Wold-style-definition CDIAGFLAGS+= -Wparentheses CDIAGFLAGS+= -Wpointer-arith CDIAGFLAGS+= -Wreturn-type @@ -48,9 +50,6 @@ CDIAGFLAGS+= -Wtrigraphs CDIAGFLAGS+= -Wuninitialized CDIAGFLAGS+= -Wunused CDIAGFLAGS+= -Wno-unused-parameter -.if ${COMPILER_VERSION:L} != "gcc3" -CDIAGFLAGS+= -Wold-style-definition -.endif CFLAGS+=-I${.CURDIR}/${SSHREL} diff --git a/regress/misc/sk-dummy/fatal.c b/regress/misc/sk-dummy/fatal.c index c6e4b5d..4f5e885 100644 --- a/regress/misc/sk-dummy/fatal.c +++ b/regress/misc/sk-dummy/fatal.c @@ -10,18 +10,36 @@ #include "log.h" void -sshfatal(const char *file, const char *func, int line, int showfunc, - LogLevel level, const char *suffix, const char *fmt, ...) +sshlogv(const char *file, const char *func, int line, int showfunc, + LogLevel level, const char *suffix, const char *fmt, va_list args) { - va_list ap; - if (showfunc) fprintf(stderr, "%s: ", func); - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); + vfprintf(stderr, fmt, args); if (suffix != NULL) fprintf(stderr, ": %s", suffix); fputc('\n', stderr); +} + +void +sshlog(const char *file, const char *func, int line, int showfunc, + LogLevel level, const char *suffix, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + sshlogv(file, func, line, showfunc, level, suffix, fmt, args); + va_end(args); +} + +void +sshfatal(const char *file, const char *func, int line, int showfunc, + LogLevel level, const char *suffix, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + sshlogv(file, func, line, showfunc, level, suffix, fmt, args); + va_end(args); _exit(1); } diff --git a/regress/misc/sk-dummy/sk-dummy.c b/regress/misc/sk-dummy/sk-dummy.c index 347b212..4c96e88 100644 --- a/regress/misc/sk-dummy/sk-dummy.c +++ b/regress/misc/sk-dummy/sk-dummy.c @@ -1,3 +1,4 @@ +/* $OpenBSD: sk-dummy.c,v 1.16 2025/06/17 01:24:32 djm Exp $ */ /* * Copyright (c) 2019 Markus Friedl * @@ -16,9 +17,7 @@ #include "includes.h" -#ifdef HAVE_STDINT_H #include -#endif #include #include #include @@ -263,7 +262,7 @@ sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len, break; default: skdebug(__func__, "unsupported key type %d", alg); - return -1; + goto out; } /* Have to return something here */ if ((response->signature = calloc(1, 1)) == NULL) { @@ -520,7 +519,7 @@ sk_sign(uint32_t alg, const uint8_t *data, size_t datalen, break; default: skdebug(__func__, "unsupported key type %d", alg); - return -1; + goto out; } *sign_response = response; response = NULL; diff --git a/regress/misc/ssh-verify-attestation/Makefile b/regress/misc/ssh-verify-attestation/Makefile new file mode 100644 index 0000000..2124b78 --- /dev/null +++ b/regress/misc/ssh-verify-attestation/Makefile @@ -0,0 +1,76 @@ +# $OpenBSD: Makefile,v 1.4 2025/11/06 01:33:03 djm Exp $ + +.include +.include + +PROG= ssh-verify-attestation +NOMAN= + +SSHREL=../../../../../usr.bin/ssh +.PATH: ${.CURDIR}/${SSHREL} + +SRCS=ssh-verify-attestation.c +# From usr.bin/ssh +SRCS+=sshbuf-getput-basic.c sshbuf-getput-crypto.c sshbuf-misc.c sshbuf.c +SRCS+=sshbuf-io.c atomicio.c sshkey.c authfile.c cipher.c log.c ssh-rsa.c +SRCS+=ssh-ecdsa.c ssh-ed25519.c mac.c umac.c umac128.c hmac.c misc.c +SRCS+=ssherr.c uidswap.c cleanup.c xmalloc.c match.c krl.c fatal.c +SRCS+=addr.c addrmatch.c bitmap.c +SRCS+=cipher-chachapoly.c chacha.c poly1305.c ssh-ecdsa-sk.c ssh-sk.c +SRCS+=ssh-ed25519-sk.c sk-usbhid.c + +SRCS+=digest-openssl.c ed25519-openssl.c +#SRCS+=digest-libc.c ed25519.c +SRCS+=utf8.c + +OPENSSL?= yes + +.if (${OPENSSL:L} == "yes") +CFLAGS+= -DWITH_OPENSSL +.endif + +# enable warnings +WARNINGS=Yes + +DEBUG=-g +CFLAGS+= -fstack-protector-all +CDIAGFLAGS= -Wall +CDIAGFLAGS+= -Wextra +CDIAGFLAGS+= -Werror +CDIAGFLAGS+= -Wchar-subscripts +CDIAGFLAGS+= -Wcomment +CDIAGFLAGS+= -Wformat +CDIAGFLAGS+= -Wformat-security +CDIAGFLAGS+= -Wimplicit +CDIAGFLAGS+= -Winline +CDIAGFLAGS+= -Wmissing-declarations +CDIAGFLAGS+= -Wmissing-prototypes +CDIAGFLAGS+= -Wold-style-definition +CDIAGFLAGS+= -Wparentheses +CDIAGFLAGS+= -Wpointer-arith +CDIAGFLAGS+= -Wreturn-type +CDIAGFLAGS+= -Wshadow +CDIAGFLAGS+= -Wsign-compare +CDIAGFLAGS+= -Wstrict-aliasing +CDIAGFLAGS+= -Wstrict-prototypes +CDIAGFLAGS+= -Wswitch +CDIAGFLAGS+= -Wtrigraphs +CDIAGFLAGS+= -Wuninitialized +CDIAGFLAGS+= -Wunused +CDIAGFLAGS+= -Wno-unused-parameter + +CFLAGS+=-I${.CURDIR}/${SSHREL} + +.if (${OPENSSL:L} == "yes") +LDADD+= -lcrypto +DPADD+= ${LIBCRYPTO} +.endif + +LDADD+= -lfido2 -lcbor +DPADD+= ${LIBFIDO2} ${LIBCBOR} + +LDADD+= -lutil +DPADD+= ${LIBUTIL} + +.include + diff --git a/regress/misc/ssh-verify-attestation/ssh-verify-attestation.c b/regress/misc/ssh-verify-attestation/ssh-verify-attestation.c new file mode 100644 index 0000000..da7f5a2 --- /dev/null +++ b/regress/misc/ssh-verify-attestation/ssh-verify-attestation.c @@ -0,0 +1,434 @@ +/* $OpenBSD: ssh-verify-attestation.c,v 1.3 2025/05/12 05:42:02 tb Exp $ */ +/* + * Copyright (c) 2022-2024 Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* + * This is a small program to verify FIDO attestation objects that + * ssh-keygen(1) can record when enrolling a FIDO key. It requires that + * the attestation object and challenge used when creating the key be + * recorded. + * + * Example usage: + * + * $ # Generate a random challenge. + * $ dd if=/dev/urandom of=key_ecdsa_sk.challenge bs=32 count=1 + * $ # Generate a key, record the attestation blob. + * $ ssh-keygen -f key_ecdsa_sk -t ecdsa-sk \ + * -Ochallenge=key_ecdsa_sk.challenge \ + * -Owrite-attestation=key_ecdsa_sk.attest -N '' + * $ # Validate the challenge (-A = print attestation CA cert) + * $ ./obj/ssh-verify-attestation -A key_ecdsa_sk key_ecdsa_sk.challenge \ + * key_ecdsa_sk.attest + * + * Limitations/TODO: + * + * 1) It doesn't automatically detect the attestation statement format. It + * assumes the "packed" format used by FIDO2 keys. If that doesn't work, + * then try using the -U option to select the "fido-u2f" format. + * 2) It makes assumptions about RK, UV, etc status of the key/cred. + * 3) Probably bugs. + * + * Thanks to Markus Friedl and Pedro Martelletto for help getting this + * working. + */ + +#include "includes.h" + +#include +#include +#include +#include +#include +#include + +#include "xmalloc.h" +#include "log.h" +#include "sshbuf.h" +#include "sshkey.h" +#include "authfile.h" +#include "ssherr.h" +#include "misc.h" +#include "digest.h" +#include "crypto_api.h" + +#include +#include +#include +#include +#include +#include +#include "openbsd-compat/openssl-compat.h" + +extern char *__progname; + +#define ATTEST_MAGIC "ssh-sk-attest-v01" + +static int +prepare_fido_cred(fido_cred_t *cred, int credtype, const char *attfmt, + const char *rp_id, struct sshbuf *b, const struct sshbuf *challenge, + struct sshbuf **attestation_certp) +{ + struct sshbuf *attestation_cert = NULL, *sig = NULL, *authdata = NULL; + char *magic = NULL; + int r = SSH_ERR_INTERNAL_ERROR; + + *attestation_certp = NULL; + + /* Make sure it's the format we're expecting */ + if ((r = sshbuf_get_cstring(b, &magic, NULL)) != 0) { + error_fr(r, "parse header"); + goto out; + } + if (strcmp(magic, ATTEST_MAGIC) != 0) { + error_f("unsupported format"); + r = SSH_ERR_INVALID_FORMAT; + goto out; + } + /* Parse the remaining fields */ + if ((r = sshbuf_froms(b, &attestation_cert)) != 0 || + (r = sshbuf_froms(b, &sig)) != 0 || + (r = sshbuf_froms(b, &authdata)) != 0 || + (r = sshbuf_get_u32(b, NULL)) != 0 || /* reserved flags */ + (r = sshbuf_get_string_direct(b, NULL, NULL)) != 0) { /* reserved */ + error_fr(r, "parse body"); + goto out; + } + debug3_f("attestation cert len=%zu, sig len=%zu, " + "authdata len=%zu challenge len=%zu", sshbuf_len(attestation_cert), + sshbuf_len(sig), sshbuf_len(authdata), sshbuf_len(challenge)); + + fido_cred_set_type(cred, credtype); + fido_cred_set_fmt(cred, attfmt); + fido_cred_set_clientdata(cred, sshbuf_ptr(challenge), + sshbuf_len(challenge)); + fido_cred_set_rp(cred, rp_id, NULL); + fido_cred_set_authdata(cred, sshbuf_ptr(authdata), + sshbuf_len(authdata)); + /* XXX set_extensions, set_rk, set_uv */ + fido_cred_set_x509(cred, sshbuf_ptr(attestation_cert), + sshbuf_len(attestation_cert)); + fido_cred_set_sig(cred, sshbuf_ptr(sig), sshbuf_len(sig)); + + /* success */ + *attestation_certp = attestation_cert; + attestation_cert = NULL; + r = 0; + out: + free(magic); + sshbuf_free(attestation_cert); + sshbuf_free(sig); + sshbuf_free(authdata); + return r; +} + +static uint8_t * +get_pubkey_from_cred_ecdsa(const fido_cred_t *cred, size_t *pubkey_len) +{ + const uint8_t *ptr; + uint8_t *pubkey = NULL, *ret = NULL; + BIGNUM *x = NULL, *y = NULL; + EC_POINT *q = NULL; + EC_GROUP *g = NULL; + + if ((x = BN_new()) == NULL || + (y = BN_new()) == NULL || + (g = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1)) == NULL || + (q = EC_POINT_new(g)) == NULL) { + error_f("libcrypto setup failed"); + goto out; + } + if ((ptr = fido_cred_pubkey_ptr(cred)) == NULL) { + error_f("fido_cred_pubkey_ptr failed"); + goto out; + } + if (fido_cred_pubkey_len(cred) != 64) { + error_f("bad fido_cred_pubkey_len %zu", + fido_cred_pubkey_len(cred)); + goto out; + } + + if (BN_bin2bn(ptr, 32, x) == NULL || + BN_bin2bn(ptr + 32, 32, y) == NULL) { + error_f("BN_bin2bn failed"); + goto out; + } + if (EC_POINT_set_affine_coordinates(g, q, x, y, NULL) != 1) { + error_f("EC_POINT_set_affine_coordinates failed"); + goto out; + } + *pubkey_len = EC_POINT_point2oct(g, q, + POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); + if (*pubkey_len == 0 || *pubkey_len > 2048) { + error_f("bad pubkey length %zu", *pubkey_len); + goto out; + } + if ((pubkey = malloc(*pubkey_len)) == NULL) { + error_f("malloc pubkey failed"); + goto out; + } + if (EC_POINT_point2oct(g, q, POINT_CONVERSION_UNCOMPRESSED, + pubkey, *pubkey_len, NULL) == 0) { + error_f("EC_POINT_point2oct failed"); + goto out; + } + /* success */ + ret = pubkey; + pubkey = NULL; + out: + free(pubkey); + EC_POINT_free(q); + EC_GROUP_free(g); + BN_clear_free(x); + BN_clear_free(y); + return ret; +} + +/* copied from sshsk_ecdsa_assemble() */ +static int +cred_matches_key_ecdsa(const fido_cred_t *cred, const struct sshkey *k) +{ + struct sshkey *key = NULL; + struct sshbuf *b = NULL; + EC_KEY *ec = NULL; + uint8_t *pubkey = NULL; + size_t pubkey_len; + int r; + + if ((key = sshkey_new(KEY_ECDSA_SK)) == NULL) { + error_f("sshkey_new failed"); + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + key->ecdsa_nid = NID_X9_62_prime256v1; + if ((key->pkey = EVP_PKEY_new()) == NULL || + (ec = EC_KEY_new_by_curve_name(key->ecdsa_nid)) == NULL || + (b = sshbuf_new()) == NULL) { + error_f("allocation failed"); + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((pubkey = get_pubkey_from_cred_ecdsa(cred, &pubkey_len)) == NULL) { + error_f("get_pubkey_from_cred_ecdsa failed"); + r = SSH_ERR_INVALID_FORMAT; + goto out; + } + if ((r = sshbuf_put_string(b, pubkey, pubkey_len)) != 0) { + error_fr(r, "sshbuf_put_string"); + goto out; + } + if ((r = sshbuf_get_eckey(b, ec)) != 0) { + error_fr(r, "parse"); + r = SSH_ERR_INVALID_FORMAT; + goto out; + } + if (sshkey_ec_validate_public(EC_KEY_get0_group(ec), + EC_KEY_get0_public_key(ec)) != 0) { + error("Authenticator returned invalid ECDSA key"); + r = SSH_ERR_KEY_INVALID_EC_VALUE; + goto out; + } + if (EVP_PKEY_set1_EC_KEY(key->pkey, ec) != 1) { + /* XXX assume it is a allocation error */ + error_f("allocation failed"); + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + key->sk_application = xstrdup(k->sk_application); /* XXX */ + if (!sshkey_equal_public(key, k)) { + error("sshkey_equal_public failed"); + r = SSH_ERR_INVALID_ARGUMENT; + goto out; + } + r = 0; /* success */ + out: + EC_KEY_free(ec); + free(pubkey); + sshkey_free(key); + sshbuf_free(b); + return r; +} + + +/* copied from sshsk_ed25519_assemble() */ +static int +cred_matches_key_ed25519(const fido_cred_t *cred, const struct sshkey *k) +{ + struct sshkey *key = NULL; + const uint8_t *ptr; + int r = -1; + + if ((ptr = fido_cred_pubkey_ptr(cred)) == NULL) { + error_f("fido_cred_pubkey_ptr failed"); + goto out; + } + if (fido_cred_pubkey_len(cred) != ED25519_PK_SZ) { + error_f("bad fido_cred_pubkey_len %zu", + fido_cred_pubkey_len(cred)); + goto out; + } + + if ((key = sshkey_new(KEY_ED25519_SK)) == NULL) { + error_f("sshkey_new failed"); + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((key->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) { + error_f("malloc failed"); + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + memcpy(key->ed25519_pk, ptr, ED25519_PK_SZ); + key->sk_application = xstrdup(k->sk_application); /* XXX */ + if (!sshkey_equal_public(key, k)) { + error("sshkey_equal_public failed"); + r = SSH_ERR_INVALID_ARGUMENT; + goto out; + } + r = 0; /* success */ + out: + sshkey_free(key); + return r; +} + +static int +cred_matches_key(const fido_cred_t *cred, const struct sshkey *k) +{ + switch (sshkey_type_plain(k->type)) { + case KEY_ECDSA_SK: + switch (k->ecdsa_nid) { + case NID_X9_62_prime256v1: + return cred_matches_key_ecdsa(cred, k); + break; + default: + fatal("Unsupported ECDSA key size"); + } + break; + case KEY_ED25519_SK: + return cred_matches_key_ed25519(cred, k); + default: + error_f("key type %s not supported", sshkey_type(k)); + return -1; + } +} + +int +main(int argc, char **argv) +{ + LogLevel log_level = SYSLOG_LEVEL_INFO; + int r, ch, credtype = -1; + struct sshkey *k = NULL; + struct sshbuf *attestation = NULL, *challenge = NULL; + struct sshbuf *attestation_cert = NULL; + char *fp; + const char *attfmt = "packed", *style = NULL; + fido_cred_t *cred = NULL; + int write_attestation_cert = 0; + extern int optind; + /* extern char *optarg; */ + + ERR_load_crypto_strings(); + + sanitise_stdfd(); + log_init(__progname, log_level, SYSLOG_FACILITY_AUTH, 1); + + while ((ch = getopt(argc, argv, "UAv")) != -1) { + switch (ch) { + case 'U': + attfmt = "fido-u2f"; + break; + case 'A': + write_attestation_cert = 1; + break; + case 'v': + if (log_level == SYSLOG_LEVEL_ERROR) + log_level = SYSLOG_LEVEL_DEBUG1; + else if (log_level < SYSLOG_LEVEL_DEBUG3) + log_level++; + break; + default: + goto usage; + } + } + log_init(__progname, log_level, SYSLOG_FACILITY_AUTH, 1); + argv += optind; + argc -= optind; + + if (argc < 3) { + usage: + fprintf(stderr, "usage: %s [-vAU] " + "pubkey challenge attestation-blob\n", __progname); + exit(1); + } + if ((r = sshkey_load_public(argv[0], &k, NULL)) != 0) + fatal_r(r, "load key %s", argv[0]); + if ((fp = sshkey_fingerprint(k, SSH_FP_HASH_DEFAULT, + SSH_FP_DEFAULT)) == NULL) + fatal("sshkey_fingerprint failed"); + debug2("key %s: %s %s", argv[2], sshkey_type(k), fp); + free(fp); + if ((r = sshbuf_load_file(argv[1], &challenge)) != 0) + fatal_r(r, "load challenge %s", argv[1]); + if ((r = sshbuf_load_file(argv[2], &attestation)) != 0) + fatal_r(r, "load attestation %s", argv[2]); + if ((cred = fido_cred_new()) == NULL) + fatal("fido_cred_new failed"); + + switch (sshkey_type_plain(k->type)) { + case KEY_ECDSA_SK: + switch (k->ecdsa_nid) { + case NID_X9_62_prime256v1: + credtype = COSE_ES256; + break; + default: + fatal("Unsupported ECDSA key size"); + } + break; + case KEY_ED25519_SK: + credtype = COSE_EDDSA; + break; + default: + fatal("unsupported key type %s", sshkey_type(k)); + } + + if ((r = prepare_fido_cred(cred, credtype, attfmt, k->sk_application, + attestation, challenge, &attestation_cert)) != 0) + fatal_r(r, "prepare_fido_cred %s", argv[2]); + if (fido_cred_x5c_ptr(cred) != NULL) { + debug("basic attestation"); + if ((r = fido_cred_verify(cred)) != FIDO_OK) + fatal("basic attestation failed"); + style = "basic"; + } else { + debug("self attestation"); + if ((r = fido_cred_verify_self(cred)) != FIDO_OK) + fatal("self attestation failed"); + style = "self"; + } + if (cred_matches_key(cred, k) != 0) + fatal("cred authdata does not match key"); + + fido_cred_free(&cred); + + if (write_attestation_cert) { + PEM_write(stdout, "CERTIFICATE", NULL, + sshbuf_ptr(attestation_cert), sshbuf_len(attestation_cert)); + } + sshbuf_free(attestation_cert); + + logit("%s: verified %s attestation", argv[2], style); + + return (0); +} diff --git a/regress/modpipe.c b/regress/modpipe.c index 5f4824b..99a6e43 100644 --- a/regress/modpipe.c +++ b/regress/modpipe.c @@ -1,3 +1,5 @@ +/* $OpenBSD: modpipe.c,v 1.9 2026/03/06 07:06:45 dtucker Exp $ */ + /* * Copyright (c) 2012 Damien Miller * @@ -14,8 +16,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $OpenBSD: modpipe.c,v 1.6 2013/11/21 03:16:47 djm Exp $ */ - #include "includes.h" #include @@ -44,7 +44,7 @@ usage(void) struct modification { enum { MOD_XOR, MOD_AND_OR } what; unsigned long long offset; - u_int8_t m1, m2; + uint8_t m1, m2; }; static void @@ -127,7 +127,7 @@ main(int argc, char **argv) } } for (o = 0; o < s; o += r) { - r = write(STDOUT_FILENO, buf, s - o); + r = write(STDOUT_FILENO, buf + o, s - o); if (r == 0) break; if (r < 0) { diff --git a/regress/multiplex.sh b/regress/multiplex.sh index 8274b9d..584bbbe 100644 --- a/regress/multiplex.sh +++ b/regress/multiplex.sh @@ -1,12 +1,12 @@ -# $OpenBSD: multiplex.sh,v 1.37 2024/07/19 04:33:36 djm Exp $ +# $OpenBSD: multiplex.sh,v 1.41 2025/12/07 02:59:53 dtucker Exp $ # Placed in the Public Domain. -make_tmpdir -CTL=${SSH_REGRESS_TMP}/ctl-sock - tid="connection multiplexing" trace "will use ProxyCommand $proxycmd" +make_tmpdir +CTL=${SSH_REGRESS_TMP}/ctl-sock + if config_defined DISABLE_FD_PASSING ; then skip "not supported on this platform (FD passing disabled)" fi @@ -24,6 +24,7 @@ wait_for_mux_master_ready() } maybe_add_scp_path_to_sshd +enable_all_kexes_in_sshd start_sshd start_mux_master() @@ -180,6 +181,13 @@ N=$(echo "xyzzy" | $NC -U $OBJ/unix-1.fwd 2>&1 | grep "xyzzy" | wc -l) test ${N} -eq 0 || fail "remote forward path still listening" rm -f $OBJ/unix-1.fwd +verbose "test $tid: cmd conninfo" +conninfo=`${SSH} -F $OBJ/ssh_config -S $CTL -Oconninfo otherhost` \ + || fail "request remote forward failed" +if ! echo "$conninfo" | egrep -- "-> 127.0.0.1:$port" >/dev/null; then + fail "conninfo" +fi + verbose "test $tid: cmd exit" ${SSH} -F $OBJ/ssh_config -S $CTL -Oexit otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \ || fail "send exit command failed" @@ -188,16 +196,45 @@ ${SSH} -F $OBJ/ssh_config -S $CTL -Oexit otherhost >>$TEST_REGRESS_LOGFILE 2>&1 wait $SSH_PID kill -0 $SSH_PID >/dev/null 2>&1 && fail "exit command failed" +# Enable compression and alternative kex for next conninfo test. +if $SSH -Q compression | grep zlib@openssh.com >/dev/null; then + compression=yes +else + compression=no +fi +echo compression $compression >>$OBJ/ssh_config +echo kexalgorithms curve25519-sha256 >>$OBJ/ssh_config +echo ciphers aes128-ctr >>$OBJ/ssh_config + # Restart master and test -O stop command with master using -N verbose "test $tid: cmd stop" trace "restart master, fork to background" start_mux_master +verbose "test $tid: cmd conninfo algos" +conninfo=`${SSH} -F $OBJ/ssh_config -S $CTL -Oconninfo otherhost` \ + || fail "request remote forward failed" +if echo "$conninfo" | grep "kexalgorithm curve25519-sha256" >/dev/null && + echo "$conninfo" | grep "cipher aes128-ctr" >/dev/null; then + trace "ok conninfo algos" +else + fail "conninfo algos" +fi +if [ "$compression" = "yes" ]; then + verbose "test $tid: cmd conninfo compression" + if echo "$conninfo" | grep "compression zlib" >/dev/null && + echo "$conninfo" | grep "compressed" >/dev/null; then + trace "ok conninfo compression" + else + fail "conninfo compression" + fi +fi + # start a long-running command then immediately request a stop ${SSH} -F $OBJ/ssh_config -S $CTL otherhost "sleep 10; exit 0" \ >>$TEST_REGRESS_LOGFILE 2>&1 & SLEEP_PID=$! -${SSH} -F $OBJ/ssh_config -S $CTL -Ostop otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \ +${SSH} -F$OBJ/ssh_config -S$CTL -Ostop otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \ || fail "send stop command failed" # wait until both long-running command and master have exited. diff --git a/regress/netcat.c b/regress/netcat.c index 20ec3f5..c621117 100644 --- a/regress/netcat.c +++ b/regress/netcat.c @@ -55,13 +55,7 @@ #include #include "atomicio.h" -#ifdef HAVE_POLL_H #include -#else -# ifdef HAVE_SYS_POLL_H -# include -# endif -#endif #ifdef HAVE_ERR_H # include #endif @@ -185,6 +179,8 @@ main(int argc, char *argv[]) socksv = -1; /* HTTP proxy CONNECT */ else if (strcmp(optarg, "4") == 0) socksv = 4; /* SOCKS v.4 */ + else if (strcasecmp(optarg, "4A") == 0) + socksv = 44; /* SOCKS v.4A */ else if (strcmp(optarg, "5") == 0) socksv = 5; /* SOCKS v.5 */ else @@ -1138,7 +1134,7 @@ build_ports(char *p) char *c; for (x = 0; x <= (hi - lo); x++) { - y = (arc4random() & 0xFFFF) % (hi - lo); + y = arc4random_uniform(hi - lo); c = portlist[x]; portlist[x] = portlist[y]; portlist[y] = c; @@ -1586,19 +1582,33 @@ socks_connect(const char *host, const char *port, default: errx(1, "connection failed, unsupported address type"); } - } else if (socksv == 4) { - /* This will exit on lookup failure */ - decode_addrport(host, port, (struct sockaddr *)&addr, - sizeof(addr), 1, 0); + } else if (socksv == 4 || socksv == 44) { + if (socksv == 4) { + /* This will exit on lookup failure */ + decode_addrport(host, port, (struct sockaddr *)&addr, + sizeof(addr), 1, 0); + } /* Version 4 */ buf[0] = SOCKS_V4; buf[1] = SOCKS_CONNECT; /* connect */ memcpy(buf + 2, &in4->sin_port, sizeof in4->sin_port); - memcpy(buf + 4, &in4->sin_addr, sizeof in4->sin_addr); + if (socksv == 4) { + memcpy(buf + 4, &in4->sin_addr, sizeof in4->sin_addr); + } else { + /* SOCKS4A uses addr of 0.0.0.x, and hostname later */ + buf[4] = buf[5] = buf[6] = 0; + buf[7] = 1; + } buf[8] = 0; /* empty username */ wlen = 9; - + if (socksv == 44) { + /* SOCKS4A has nul-terminated hostname after user */ + if (strlcpy(buf + 9, host, + sizeof(buf) - 9) >= sizeof(buf) - 9) + errx(1, "hostname too big"); + wlen = 9 + strlen(host) + 1; + } cnt = atomicio(vwrite, proxyfd, buf, wlen); if (cnt != wlen) err(1, "write failed (%zu/%zu)", cnt, wlen); diff --git a/regress/password.sh b/regress/password.sh new file mode 100644 index 0000000..10f507e --- /dev/null +++ b/regress/password.sh @@ -0,0 +1,60 @@ +# $OpenBSD: password.sh,v 1.2 2025/06/29 08:20:21 dtucker Exp $ +# Placed in the Public Domain. +# +# This tests standard "password" authentication. It does not run by default, +# and needs to be enabled by putting the password of the user running the tests +# into ${OBJ}/password. Since this obviously puts the password at risk it is +# recommended to do this on a throwaway VM by setting a random password +# (and randomizing it again after the test, if you can't immediately dispose +# of the VM). + +tid="password" + +if [ -z "$SUDO" -o ! -f ${OBJ}/password ]; then + skip "Password auth requires SUDO and password file." +fi + +# Enable password auth +echo "PasswordAuthentication yes" >>sshd_proxy + +# Create askpass script to replay a series of password responses. +# Keep a counter of the number of times it has been called and +# reply with the next line of the replypass file. +cat >${OBJ}/replypass.sh <${OBJ}/replypass.N +EOD +chmod 700 ${OBJ}/replypass.sh + +SSH_ASKPASS=${OBJ}/replypass.sh +SSH_ASKPASS_REQUIRE=force +export SSH_ASKPASS SSH_ASKPASS_REQUIRE + +opts="-oPasswordAuthentication=yes -oPreferredAuthentications=password" +opts="-oBatchMode=no $opts" + +trace plain password +cat ${OBJ}/password >${OBJ}/replypass +echo 1 >${OBJ}/replypass.N +${SSH} $opts -F $OBJ/ssh_proxy somehost true +if [ $? -ne 0 ]; then + fail "ssh password failed" +fi + +trace 2-round password +(echo; cat ${OBJ}/password) >${OBJ}/replypass +echo 1 >${OBJ}/replypass.N +${SSH} $opts -F $OBJ/ssh_proxy somehost true +if [ $? -ne 0 ]; then + fail "ssh 2-round password failed" +fi + +trace empty password +echo >${OBJ}/replypass +echo 1 >${OBJ}/replypass.N +${SSH} $opts -F $OBJ/ssh_proxy somehost true +if [ $? -eq 0 ]; then + fail "ssh password failed" +fi diff --git a/regress/penalty-expire.sh b/regress/penalty-expire.sh index 4f0bbe6..27e36e3 100644 --- a/regress/penalty-expire.sh +++ b/regress/penalty-expire.sh @@ -1,4 +1,4 @@ -# $OpenBSD +# $OpenBSD: penalty-expire.sh,v 1.3 2025/05/22 04:34:18 bluhm Exp $ # Placed in the Public Domain. tid="penalties" diff --git a/regress/penalty.sh b/regress/penalty.sh index 8b83532..bf719dc 100644 --- a/regress/penalty.sh +++ b/regress/penalty.sh @@ -1,4 +1,4 @@ -# $OpenBSD +# $OpenBSD: penalty.sh,v 1.7 2025/05/22 04:34:18 bluhm Exp $ # Placed in the Public Domain. tid="penalties" diff --git a/regress/percent.sh b/regress/percent.sh index 354854f..e32a77f 100644 --- a/regress/percent.sh +++ b/regress/percent.sh @@ -1,4 +1,4 @@ -# $OpenBSD: percent.sh,v 1.17 2023/03/27 03:56:50 dtucker Exp $ +# $OpenBSD: percent.sh,v 1.23 2026/04/02 07:52:15 djm Exp $ # Placed in the Public Domain. tid="percent expansions" @@ -29,6 +29,23 @@ trial() somehost true got=`cat $OBJ/actual` ;; + user|user-l|user-at) + if [ "$arg" = '%r' ] || [ "$arg" = '%C' ]; then + # User does not support %r, ie itself or %C. Skip test. + got="$expect" + elif [ "$opt" = "user" ]; then + got=`${SSH} -F $OBJ/ssh_proxy -o $opt="$arg" -G \ + remuser@somehost | awk '$1=="'$opt'"{print $2}'` + elif [ "$opt" = "user-l" ]; then + # Also test ssh -l + got=`${SSH} -F $OBJ/ssh_proxy -l "$arg" -G \ + somehost | awk '$1=="'user'"{print $2}'` + elif [ "$opt" = "user-at" ]; then + # Also test user@host + got=`${SSH} -F $OBJ/ssh_proxy -G "$arg@somehost" | \ + awk '$1=="'user'"{print $2}'` + fi + ;; userknownhostsfile) # Move the userknownhosts file to what the expansion says, # make sure ssh works then put it back. @@ -51,6 +68,18 @@ trial() remuser@somehost | awk '$1=="'$opt'"{print $2" "$3}'` expect="/$expect /$expect" ;; + setenv) + # First make sure we don't expand variable names. + got=`${SSH} -F $OBJ/ssh_proxy -o $opt="$arg=TESTVAL" -G \ + remuser@somehost | awk '$1=="'$opt'"{print $2}'` + if [ "$got" != "$arg=TESTVAL" ]; then + fatal "incorrectly expanded setenv variable name" + fi + # Now check that the value expands as expected. + got=`${SSH} -F $OBJ/ssh_proxy -o $opt=TESTVAL="$arg" -G \ + remuser@somehost | awk '$1=="'$opt'"{print $2}'` + got=`echo "$got" | sed 's/^TESTVAL=//'` + ;; *) got=`${SSH} -F $OBJ/ssh_proxy -o $opt="$arg" -G \ remuser@somehost | awk '$1=="'$opt'"{print $2}'` @@ -62,7 +91,7 @@ trial() for i in matchexec localcommand remotecommand controlpath identityagent \ forwardagent localforward remoteforward revokedhostkeys \ - userknownhostsfile; do + user setenv userknownhostsfile; do verbose $tid $i percent case "$i" in localcommand|userknownhostsfile) @@ -77,7 +106,7 @@ for i in matchexec localcommand remotecommand controlpath identityagent \ fi # Matches implementation in readconf.c:ssh_connection_hash() if [ ! -z "${OPENSSL_BIN}" ]; then - HASH=`printf "${HOSTNAME}127.0.0.1${PORT}$REMUSER" | + HASH=`printf "${HOSTNAME}127.0.0.1${PORT}${REMUSER}" | $OPENSSL_BIN sha1 | cut -f2 -d' '` trial $i '%C' $HASH fi @@ -92,8 +121,9 @@ for i in matchexec localcommand remotecommand controlpath identityagent \ trial $i '%r' $REMUSER trial $i '%u' $USER # We can't specify a full path outside the regress dir, so skip tests - # containing %d for UserKnownHostsFile - if [ "$i" != "userknownhostsfile" ]; then + # containing %d for UserKnownHostsFile, and %r can't refer to itself. + if [ "$i" != "userknownhostsfile" ] && [ "$i" != "user" ] && \ + [ "$i" != "user-l" ] && [ "$i" != "user-at" ]; then trial $i '%d' $HOME in='%%/%i/%h/%d/%L/%l/%n/%p/%r/%u' out="%/$USERID/127.0.0.1/$HOME/$HOST/$HOSTNAME/somehost/$PORT/$REMUSER/$USER" @@ -107,11 +137,11 @@ done # Subset of above since we don't expand shell-style variables on anything that # runs a command because the shell will expand those. +FOO=bar +export FOO for i in controlpath identityagent forwardagent localforward remoteforward \ - userknownhostsfile; do + setenv userknownhostsfile; do verbose $tid $i dollar - FOO=bar - export FOO trial $i '${FOO}' $FOO done @@ -122,3 +152,32 @@ for i in controlpath identityagent forwardagent; do trial $i '~' $HOME/ trial $i '~/.ssh' $HOME/.ssh done + +for i in user-l user-at; do + verbose $tid $i noexpand + trial $i '%u' '%u' +done + +# These should be not be expanded but rejected for containing shell characters. +verbose $tid user-l noenv +${SSH} -F $OBJ/ssh_proxy -l '${FOO}' -G somehost && fail "user-l expanded env" +verbose $tid user-at noenv +${SSH} -F $OBJ/ssh_proxy -G '${FOO}@somehost' && fail "user-at expanded env" + +FOO=`printf 'x\ay'` +export FOO + +# These should be rejected as containing control characters. +verbose $tid user-l badchar +${SSH} -F $OBJ/ssh_proxy -l "${FOO}" -G somehost && fail "user-l expanded env" +verbose $tid user-at badchar +${SSH} -F $OBJ/ssh_proxy -G "${FOO}@somehost" && fail "user-at expanded env" + +# Literal control characters in config is acceptable +verbose $tid user control-literal +#trial user "$FOO" "$FOO" + +# Control characters expanded from config aren't. +${SSH} -F $OBJ/ssh_proxy -G '-oUser=${FOO}' somehost && \ + fail "user expanded ctrl" + diff --git a/regress/proxyjump.sh b/regress/proxyjump.sh new file mode 100644 index 0000000..af472e9 --- /dev/null +++ b/regress/proxyjump.sh @@ -0,0 +1,102 @@ +# $OpenBSD: proxyjump.sh,v 1.1 2026/03/30 07:19:02 djm Exp $ +# Placed in the Public Domain. + +tid="proxyjump" + +# Parsing tests +verbose "basic parsing" +for jspec in \ + "jump1" \ + "user@jump1" \ + "jump1:2222" \ + "user@jump1:2222" \ + "jump1,jump2" \ + "user1@jump1:2221,user2@jump2:2222" \ + "ssh://user@host:2223" \ + ; do + case "$jspec" in + "jump1") expected="jump1" ;; + "user@jump1") expected="user@jump1" ;; + "jump1:2222") expected="jump1:2222" ;; + "user@jump1:2222") expected="user@jump1:2222" ;; + "jump1,jump2") expected="jump1,jump2" ;; + "user1@jump1:2221,user2@jump2:2222") + expected="user1@jump1:2221,user2@jump2:2222" ;; + "ssh://user@host:2223") expected="user@host:2223" ;; + esac + f=`${SSH} -GF /dev/null -oProxyJump="$jspec" somehost | \ + awk '/^proxyjump /{print $2}'` + if [ "$f" != "$expected" ]; then + fail "ProxyJump $jspec: expected $expected, got $f" + fi + f=`${SSH} -GF /dev/null -J "$jspec" somehost | \ + awk '/^proxyjump /{print $2}'` + if [ "$f" != "$expected" ]; then + fail "ssh -J $jspec: expected $expected, got $f" + fi +done + +verbose "precedence" +f=`${SSH} -GF /dev/null -oProxyJump=none -oProxyJump=jump1 somehost | \ + grep "^proxyjump "` +if [ -n "$f" ]; then + fail "ProxyJump=none first did not win" +fi +f=`${SSH} -GF /dev/null -oProxyJump=jump -oProxyCommand=foo somehost | \ + grep "^proxyjump "` +if [ "$f" != "proxyjump jump" ]; then + fail "ProxyJump first did not win over ProxyCommand" +fi +f=`${SSH} -GF /dev/null -oProxyCommand=foo -oProxyJump=jump somehost | \ + grep "^proxycommand "` +if [ "$f" != "proxycommand foo" ]; then + fail "ProxyCommand first did not win over ProxyJump" +fi + +verbose "command-line -J invalid characters" +cp $OBJ/ssh_config $OBJ/ssh_config.orig +for jspec in \ + "host;with;semicolon" \ + "host'with'quote" \ + "host\`with\`backtick" \ + "host\$with\$dollar" \ + "host(with)brace" \ + "user;with;semicolon@host" \ + "user'with'quote@host" \ + "user\`with\`backtick@host" \ + "user(with)brace@host" ; do + ${SSH} -GF /dev/null -J "$jspec" somehost >/dev/null 2>&1 + if [ $? -ne 255 ]; then + fail "ssh -J \"$jspec\" was not rejected" + fi + ${SSH} -GF /dev/null -oProxyJump="$jspec" somehost >/dev/null 2>&1 + if [ $? -ne 255 ]; then + fail "ssh -oProxyJump=\"$jspec\" was not rejected" + fi +done +# Special characters should be accepted in the config though. +echo "ProxyJump user;with;semicolon@host;with;semicolon" >> $OBJ/ssh_config +f=`${SSH} -GF $OBJ/ssh_config somehost | grep "^proxyjump "` +if [ "$f" != "proxyjump user;with;semicolon@host;with;semicolon" ]; then + fail "ProxyJump did not allow special characters in config: $f" +fi + +verbose "functional test" +# Use different names to avoid the loop detection in ssh.c +grep -iv HostKeyAlias $OBJ/ssh_config.orig > $OBJ/ssh_config +cat << _EOF >> $OBJ/ssh_config +Host jump-host + HostkeyAlias jump-host +Host target-host + HostkeyAlias target-host +_EOF +cp $OBJ/known_hosts $OBJ/known_hosts.orig +sed 's/^[^ ]* /jump-host /' < $OBJ/known_hosts.orig > $OBJ/known_hosts +sed 's/^[^ ]* /target-host /' < $OBJ/known_hosts.orig >> $OBJ/known_hosts +start_sshd + +verbose "functional ProxyJump" +res=`${REAL_SSH} -F $OBJ/ssh_config -J jump-host target-host echo "SUCCESS" 2>/dev/null` +if [ "$res" != "SUCCESS" ]; then + fail "functional test failed: expected SUCCESS, got $res" +fi diff --git a/regress/rekey.sh b/regress/rekey.sh index 3f5e1d5..8843030 100644 --- a/regress/rekey.sh +++ b/regress/rekey.sh @@ -11,7 +11,7 @@ cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak echo "Compression no" >> $OBJ/ssh_proxy echo "RekeyLimit 256k" >> $OBJ/ssh_proxy -echo "KexAlgorithms curve25519-sha256" >> ssh_proxy +echo "KexAlgorithms curve25519-sha256" >> $OBJ/ssh_proxy # Test rekeying based on data volume only. # Arguments: rekeylimit, kex method, optional remaining opts are passed to ssh. diff --git a/regress/scp.sh b/regress/scp.sh index 640cf43..98f4512 100644 --- a/regress/scp.sh +++ b/regress/scp.sh @@ -1,4 +1,4 @@ -# $OpenBSD: scp.sh,v 1.19 2023/09/08 05:50:57 djm Exp $ +# $OpenBSD: scp.sh,v 1.20 2025/10/13 00:55:09 djm Exp $ # Placed in the Public Domain. tid="scp" @@ -199,6 +199,19 @@ for mode in scp sftp ; do echo b > ${COPY2} $SCP $scpopts ${DATA} ${COPY} ${COPY2} cmp ${COPY} ${COPY2} >/dev/null && fail "corrupt target" + + # scp /blah/.. is only supported via the sftp protocol. + # Original protocol scp just refuses it. + test $mode != sftp && continue + verbose "$tag: recursive local .. to remote dir" + forest + $SCP $scpopts -r ${DIR}/subdir/.. somehost:${DIR2} || fail "copy failed" + diff ${DIFFOPT} ${DIR} ${DIR2} || fail "corrupted copy" + + verbose "$tag: recursive remote .. to local dir" + forest + $SCP $scpopts -r somehost:${DIR}/subdir/.. ${DIR2} || fail "copy failed" + diff ${DIFFOPT} ${DIR} ${DIR2} || fail "corrupted copy" done scpclean diff --git a/regress/scp3.sh b/regress/scp3.sh index eeb7a9d..d42abc2 100644 --- a/regress/scp3.sh +++ b/regress/scp3.sh @@ -1,4 +1,4 @@ -# $OpenBSD: scp3.sh,v 1.5 2023/09/08 06:10:57 djm Exp $ +# $OpenBSD: scp3.sh,v 1.6 2025/10/13 00:56:15 djm Exp $ # Placed in the Public Domain. tid="scp3" @@ -6,6 +6,12 @@ tid="scp3" COPY2=${OBJ}/copy2 DIR=${COPY}.dd DIR2=${COPY}.dd2 +DIFFOPT="-rN" + +# Figure out if diff does not understand "-N" +if ! diff -N ${SRC}/scp.sh ${SRC}/scp.sh 2>/dev/null; then + DIFFOPT="-r" +fi maybe_add_scp_path_to_sshd @@ -63,6 +69,15 @@ for mode in scp sftp ; do echo b > ${COPY2} $SCP $scpopts -3 hostA:${DATA} hostA:${COPY} hostB:${COPY2} cmp ${COPY} ${COPY2} >/dev/null && fail "corrupt target" + + # scp /blah/.. is only supported via the sftp protocol. + # Original protocol scp just refuses it. + test $mode != sftp && continue + verbose "$tag: recursive .." + forest + $SCP $scpopts -r hostA:${DIR}/subdir/.. hostB:${DIR2} || \ + fail "copy failed" + diff ${DIFFOPT} ${DIR} ${DIR2} || fail "corrupted copy" done scpclean diff --git a/regress/servcfginclude.sh b/regress/servcfginclude.sh index 518a703..f67c3ca 100644 --- a/regress/servcfginclude.sh +++ b/regress/servcfginclude.sh @@ -4,14 +4,14 @@ tid="server config include" cat > $OBJ/sshd_config.i << _EOF HostKey $OBJ/host.ssh-ed25519 -Match host a +Match host=a Banner /aa Match host b Banner /bb Include $OBJ/sshd_config.i.* # comment -Match host c +Match host=c Include $OBJ/sshd_config.i.* # comment Banner /cc @@ -25,7 +25,7 @@ Match Host e Banner /ee Include $OBJ/sshd_config.i.* -Match Host f +Match Host=f Include $OBJ/sshd_config.i.* Banner /ff @@ -47,13 +47,13 @@ Match host b Match host c Banner /ccc -Match Host d +Match Host=d Banner /ddd Match Host e Banner /eee -Match Host f +Match Host=f Banner /fff _EOF @@ -61,13 +61,13 @@ cat > $OBJ/sshd_config.i.2 << _EOF Match host a Banner /aaaa -Match host b +Match host=b Banner /bbbb Match host c # comment Banner /cccc -Match Host d +Match Host=d Banner /dddd Match Host e diff --git a/regress/sftp-cmds.sh b/regress/sftp-cmds.sh index 5640471..a03959d 100644 --- a/regress/sftp-cmds.sh +++ b/regress/sftp-cmds.sh @@ -1,4 +1,4 @@ -# $OpenBSD: sftp-cmds.sh,v 1.20 2024/07/01 03:10:19 djm Exp $ +# $OpenBSD: sftp-cmds.sh,v 1.23 2025/10/13 00:55:45 djm Exp $ # Placed in the Public Domain. # XXX - TODO: @@ -7,6 +7,12 @@ tid="sftp commands" +DIFFOPT="-rN" +# Figure out if diff does not understand "-N" +if ! diff -N ${SRC}/sftp-cmds.sh ${SRC}/sftp-cmds.sh 2>/dev/null; then + DIFFOPT="-r" +fi + # test that these files are readable! for i in `(cd /bin;echo l*)` do @@ -24,207 +30,246 @@ SPACECOPY_ARG="${COPY}\ this\ has\ spaces.txt" # File with glob metacharacters GLOBMETACOPY="${COPY} [metachar].txt" +sftpserver() { + ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 +} + +sftpserver_with_stdout() { + ${SFTP} -D ${SFTPSERVER} 2>&1 +} + +forest() { + rm -rf ${COPY}.dd/* + rm -rf ${COPY}.dd2 + mkdir -p ${COPY}.dd/a ${COPY}.dd/b ${COPY}.dd/c ${COPY}.dd/a/d + echo 'A' > ${COPY}.dd/a/A + echo 'B' > ${COPY}.dd/a/B + echo 'C' > ${COPY}.dd/a/C + echo 'D' > ${COPY}.dd/a/D +} + rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${COPY}.dd2 mkdir ${COPY}.dd verbose "$tid: lls" -printf "lcd ${OBJ}\nlls\n" | ${SFTP} -D ${SFTPSERVER} 2>&1 | \ +printf "lcd ${OBJ}\nlls\n" | sftpserver_with_stdout | \ grep copy.dd >/dev/null || fail "lls failed" verbose "$tid: lls w/path" -echo "lls ${OBJ}" | ${SFTP} -D ${SFTPSERVER} 2>&1 | \ +echo "lls ${OBJ}" | sftpserver_with_stdout | \ grep copy.dd >/dev/null || fail "lls w/path failed" verbose "$tid: ls" -echo "ls ${OBJ}" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ - || fail "ls failed" +echo "ls ${OBJ}" | sftpserver || fail "ls failed" # XXX always successful verbose "$tid: shell" -echo "!echo hi there" | ${SFTP} -D ${SFTPSERVER} 2>&1 | \ +echo "!echo hi there" | sftpserver_with_stdout | \ egrep '^hi there$' >/dev/null || fail "shell failed" verbose "$tid: pwd" -echo "pwd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ - || fail "pwd failed" +echo "pwd" | sftpserver || fail "pwd failed" # XXX always successful verbose "$tid: lpwd" -echo "lpwd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ - || fail "lpwd failed" +echo "lpwd" | sftpserver || fail "lpwd failed" # XXX always successful verbose "$tid: quit" -echo "quit" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ - || fail "quit failed" +echo "quit" | sftpserver || fail "quit failed" # XXX always successful verbose "$tid: help" -echo "help" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ - || fail "help failed" +echo "help" | sftpserver || fail "help failed" # XXX always successful rm -f ${COPY} verbose "$tid: get" -echo "get $DATA $COPY" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ - || fail "get failed" +echo "get $DATA $COPY" | sftpserver || fail "get failed" cmp $DATA ${COPY} || fail "corrupted copy after get" rm -f ${COPY} verbose "$tid: get quoted" -echo "get \"$DATA\" $COPY" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ - || fail "get failed" +echo "get \"$DATA\" $COPY" | sftpserver || fail "get failed" cmp $DATA ${COPY} || fail "corrupted copy after get" rm -f ${QUOTECOPY} cp $DATA ${QUOTECOPY} verbose "$tid: get filename with quotes" -echo "get \"$QUOTECOPY_ARG\" ${COPY}" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ - || fail "get failed" +echo "get \"$QUOTECOPY_ARG\" ${COPY}" | sftpserver || fail "get failed" cmp ${COPY} ${QUOTECOPY} || fail "corrupted copy after get with quotes" rm -f ${QUOTECOPY} ${COPY} rm -f "$SPACECOPY" ${COPY} cp $DATA "$SPACECOPY" verbose "$tid: get filename with spaces" -echo "get ${SPACECOPY_ARG} ${COPY}" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ - || fail "get failed" +echo "get ${SPACECOPY_ARG} ${COPY}" | sftpserver || fail "get failed" cmp ${COPY} "$SPACECOPY" || fail "corrupted copy after get with spaces" rm -f "$GLOBMETACOPY" ${COPY} cp $DATA "$GLOBMETACOPY" verbose "$tid: get filename with glob metacharacters" -echo "get \"${GLOBMETACOPY}\" ${COPY}" | \ - ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "get failed" +echo "get \"${GLOBMETACOPY}\" ${COPY}" | sftpserver || fail "get failed" cmp ${COPY} "$GLOBMETACOPY" || \ fail "corrupted copy after get with glob metacharacters" -rm -f ${COPY}.dd/* +rm -rf ${COPY}.dd/* verbose "$tid: get to directory" -echo "get $DATA ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ - || fail "get failed" +echo "get $DATA ${COPY}.dd" | sftpserver || fail "get failed" cmp $DATA ${COPY}.dd/${DATANAME} || fail "corrupted copy after get" -rm -f ${COPY}.dd/* +rm -rf ${COPY}.dd/* verbose "$tid: glob get to directory" -echo "get /bin/l* ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ - || fail "get failed" +echo "get /bin/l* ${COPY}.dd" | sftpserver || fail "get failed" for x in $GLOBFILES; do cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after get" done -rm -f ${COPY}.dd/* +rm -rf ${COPY}.dd/* verbose "$tid: get to local dir" -printf "lcd ${COPY}.dd\nget $DATA\n" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ - || fail "get failed" +printf "lcd ${COPY}.dd\nget $DATA\n" | sftpserver || fail "get failed" cmp $DATA ${COPY}.dd/${DATANAME} || fail "corrupted copy after get" -rm -f ${COPY}.dd/* +rm -rf ${COPY}.dd/* verbose "$tid: glob get to local dir" -printf "lcd ${COPY}.dd\nget /bin/l*\n" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ - || fail "get failed" +printf "lcd ${COPY}.dd\nget /bin/l*\n" | sftpserver || fail "get failed" for x in $GLOBFILES; do cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after get" done +forest +verbose "$tid: get recursive absolute" +echo "get -R ${COPY}.dd ${COPY}.dd2" | sftpserver || fail "get failed" +diff ${DIFFOPT} ${COPY}.dd ${COPY}.dd2 || fail "corrupted copy" + +forest +verbose "$tid: get recursive relative src" +printf "cd ${COPY}.dd\n get -R . ${COPY}.dd2\n" | sftpserver || \ + fail "get failed" +diff ${DIFFOPT} ${COPY}.dd ${COPY}.dd2 || fail "corrupted copy" + +forest +verbose "$tid: get relative .." +printf "cd ${COPY}.dd/b\n get -R .. ${COPY}.dd2\n" | sftpserver || \ + fail "get failed" +diff ${DIFFOPT} ${COPY}.dd ${COPY}.dd2 || fail "corrupted copy" + +forest +mkdir ${COPY}.dd2 +verbose "$tid: get recursive relative .." +printf "cd ${COPY}.dd/b\n lcd ${COPY}.dd2\n get -R ..\n" | sftpserver || \ + fail "get failed" +diff ${DIFFOPT} ${COPY}.dd ${COPY}.dd2 || fail "corrupted copy" + rm -f ${COPY} verbose "$tid: put" -echo "put $DATA $COPY" | \ - ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "put failed" +echo "put $DATA $COPY" | sftpserver || fail "put failed" cmp $DATA ${COPY} || fail "corrupted copy after put" rm -f ${QUOTECOPY} verbose "$tid: put filename with quotes" -echo "put $DATA \"$QUOTECOPY_ARG\"" | \ - ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "put failed" +echo "put $DATA \"$QUOTECOPY_ARG\"" | sftpserver || fail "put failed" cmp $DATA ${QUOTECOPY} || fail "corrupted copy after put with quotes" rm -f "$SPACECOPY" verbose "$tid: put filename with spaces" -echo "put $DATA ${SPACECOPY_ARG}" | \ - ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "put failed" +echo "put $DATA ${SPACECOPY_ARG}" | sftpserver || fail "put failed" cmp $DATA "$SPACECOPY" || fail "corrupted copy after put with spaces" -rm -f ${COPY}.dd/* +rm -rf ${COPY}.dd/* verbose "$tid: put to directory" -echo "put $DATA ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ - || fail "put failed" +echo "put $DATA ${COPY}.dd" | sftpserver || fail "put failed" cmp $DATA ${COPY}.dd/${DATANAME} || fail "corrupted copy after put" -rm -f ${COPY}.dd/* +rm -rf ${COPY}.dd/* verbose "$tid: glob put to directory" -echo "put /bin/l? ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ - || fail "put failed" +echo "put /bin/l? ${COPY}.dd" | sftpserver || fail "put failed" for x in $GLOBFILES; do cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after put" done -rm -f ${COPY}.dd/* +rm -rf ${COPY}.dd/* verbose "$tid: put to local dir" -printf "cd ${COPY}.dd\nput $DATA\n" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ - || fail "put failed" +printf "cd ${COPY}.dd\nput $DATA\n" | sftpserver || fail "put failed" cmp $DATA ${COPY}.dd/${DATANAME} || fail "corrupted copy after put" -rm -f ${COPY}.dd/* +rm -rf ${COPY}.dd/* verbose "$tid: glob put to local dir" -printf "cd ${COPY}.dd\nput /bin/l*\n" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ - || fail "put failed" +printf "cd ${COPY}.dd\nput /bin/l*\n" | sftpserver || fail "put failed" for x in $GLOBFILES; do cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after put" done +forest +verbose "$tid: put recursive absolute" +echo "put -R ${COPY}.dd ${COPY}.dd2" | sftpserver || fail "put failed" +diff ${DIFFOPT} ${COPY}.dd ${COPY}.dd2 || fail "corrupted copy" + +forest +verbose "$tid: put recursive relative src" +printf "lcd ${COPY}.dd\n put -R . ${COPY}.dd2\n" | sftpserver || \ + fail "put failed" +diff ${DIFFOPT} ${COPY}.dd ${COPY}.dd2 || fail "corrupted copy" + +forest +verbose "$tid: put recursive .." +printf "lcd ${COPY}.dd/b\n put -R .. ${COPY}.dd2\n" | sftpserver || \ + fail "put failed" +diff ${DIFFOPT} ${COPY}.dd ${COPY}.dd2 || fail "corrupted copy" + +forest +mkdir ${COPY}.dd2 +verbose "$tid: put recursive .. relative" +printf "lcd ${COPY}.dd/b\n cd ${COPY}.dd2\n put -R ..\n" | sftpserver || \ + fail "put failed" +diff ${DIFFOPT} ${COPY}.dd ${COPY}.dd2 || fail "corrupted copy" + verbose "$tid: rename" -echo "rename $COPY ${COPY}.1" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ - || fail "rename failed" +echo "rename $COPY ${COPY}.1" | sftpserver || fail "rename failed" test -f ${COPY}.1 || fail "missing file after rename" cmp $DATA ${COPY}.1 >/dev/null 2>&1 || fail "corrupted copy after rename" verbose "$tid: rename directory" -echo "rename ${COPY}.dd ${COPY}.dd2" | \ - ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || \ +rm -rf ${COPY}.dd2 +echo "rename ${COPY}.dd ${COPY}.dd2" | sftpserver || \ fail "rename directory failed" test -d ${COPY}.dd && fail "oldname exists after rename directory" test -d ${COPY}.dd2 || fail "missing newname after rename directory" verbose "$tid: ln" -echo "ln ${COPY}.1 ${COPY}.2" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "ln failed" +echo "ln ${COPY}.1 ${COPY}.2" | sftpserver || fail "ln failed" test -f ${COPY}.2 || fail "missing file after ln" cmp ${COPY}.1 ${COPY}.2 || fail "created file is not equal after ln" verbose "$tid: ln -s" rm -f ${COPY}.2 -echo "ln -s ${COPY}.1 ${COPY}.2" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "ln -s failed" +echo "ln -s ${COPY}.1 ${COPY}.2" | sftpserver || fail "ln -s failed" test -h ${COPY}.2 || fail "missing file after ln -s" verbose "$tid: cp" rm -f ${COPY}.2 -echo "cp ${COPY}.1 ${COPY}.2" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "cp failed" +echo "cp ${COPY}.1 ${COPY}.2" | sftpserver || fail "cp failed" cmp ${COPY}.1 ${COPY}.2 || fail "created file is not equal after cp" verbose "$tid: mkdir" -echo "mkdir ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ - || fail "mkdir failed" +echo "mkdir ${COPY}.dd" | sftpserver || fail "mkdir failed" test -d ${COPY}.dd || fail "missing directory after mkdir" # XXX do more here verbose "$tid: chdir" -echo "chdir ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ - || fail "chdir failed" +echo "chdir ${COPY}.dd" | sftpserver || fail "chdir failed" verbose "$tid: rmdir" -echo "rmdir ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ - || fail "rmdir failed" +echo "rmdir ${COPY}.dd" | sftpserver || fail "rmdir failed" test -d ${COPY}.1 && fail "present directory after rmdir" verbose "$tid: lmkdir" -echo "lmkdir ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ - || fail "lmkdir failed" +echo "lmkdir ${COPY}.dd" | sftpserver || fail "lmkdir failed" test -d ${COPY}.dd || fail "missing directory after lmkdir" # XXX do more here verbose "$tid: lchdir" -echo "lchdir ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ - || fail "lchdir failed" +echo "lchdir ${COPY}.dd" | sftpserver || fail "lchdir failed" rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${COPY}.dd2 rm -rf ${QUOTECOPY} "$SPACECOPY" "$GLOBMETACOPY" diff --git a/regress/sftp-resume.sh b/regress/sftp-resume.sh new file mode 100644 index 0000000..4ab0f1d --- /dev/null +++ b/regress/sftp-resume.sh @@ -0,0 +1,41 @@ +# $OpenBSD: sftp-resume.sh,v 1.2 2025/03/11 09:06:50 dtucker Exp $ +# Placed in the Public Domain. + +tid="sftp resume" + +CLIENT_LOG=${OBJ}/sftp.log + +# We test up to 1MB, ensure source data is large enough. +increase_datafile_size 1200 + +for cmd in put get; do + verbose "$tid: ${cmd}" + for size in 0 1 1k 1024k size-1 same; do + trace "$tid: test ${cmd} ${size}" + rm -rf ${COPY}.1 ${COPY}.2 + cp ${DATA} ${COPY}.1 + + # Set up requested source and destination file sizes. + case "${size}" in + 0) touch ${COPY}.2 + ;; + size-1) dd if=${DATA} of=${COPY}.1 bs=1024 count=1 >/dev/null 2>&1 + dd if=${DATA} of=${COPY}.2 bs=1023 count=1 >/dev/null 2>&1 + ;; + same) cp ${DATA} ${COPY}.2 + ;; + *) dd if=${COPY}.1 of=${COPY}.2 bs=${size} count=1 >/dev/null 2>&1 + ;; + esac + + # Perform copy and check. + echo "${cmd} -a ${COPY}.1 ${COPY}.2" | \ + ${SFTP} -D ${SFTPSERVER} -vvv >${CLIENT_LOG} 2>&1 \ + || fail "${cmd} failed" + cmp ${COPY}.1 ${COPY}.2 || fail "corrupted copy after ${cmd} ${size}" + grep "reordered" ${CLIENT_LOG} >/dev/null && \ + fail "server reordered requests ${cmd} ${size}" + done +done + +rm -rf ${COPY}.1 ${COPY}.2 diff --git a/regress/ssh-com-client.sh b/regress/ssh-com-client.sh index e4f80cf..97b36b5 100644 --- a/regress/ssh-com-client.sh +++ b/regress/ssh-com-client.sh @@ -1,4 +1,4 @@ -# $OpenBSD: ssh-com-client.sh,v 1.7 2013/05/17 04:29:14 dtucker Exp $ +# $OpenBSD: ssh-com-client.sh,v 1.8 2025/05/06 06:05:48 djm Exp $ # Placed in the Public Domain. tid="connect with ssh.com client" @@ -28,7 +28,7 @@ VERSIONS=" # setup authorized keys SRC=`dirname ${SCRIPT}` -cp ${SRC}/dsa_ssh2.prv ${OBJ}/id.com +cp ${SRC}/rsa_ssh2.prv ${OBJ}/id.com chmod 600 ${OBJ}/id.com ${SSHKEYGEN} -i -f ${OBJ}/id.com > $OBJ/id.openssh chmod 600 ${OBJ}/id.openssh @@ -36,8 +36,8 @@ ${SSHKEYGEN} -y -f ${OBJ}/id.openssh > $OBJ/authorized_keys_$USER ${SSHKEYGEN} -e -f ${OBJ}/id.openssh > $OBJ/id.com.pub echo IdKey ${OBJ}/id.com > ${OBJ}/id.list -# we need a DSA host key -t=dsa +# we need a RSA host key +t=rsa rm -f ${OBJ}/$t ${OBJ}/$t.pub ${SSHKEYGEN} -q -N '' -t $t -f ${OBJ}/$t $SUDO cp $OBJ/$t $OBJ/host.$t @@ -47,7 +47,6 @@ echo HostKey $OBJ/host.$t >> $OBJ/sshd_config mkdir -p ${OBJ}/${USER}/hostkeys HK=${OBJ}/${USER}/hostkeys/key_${PORT}_127.0.0.1 ${SSHKEYGEN} -e -f ${OBJ}/rsa.pub > ${HK}.ssh-rsa.pub -${SSHKEYGEN} -e -f ${OBJ}/dsa.pub > ${HK}.ssh-dss.pub cat > ${OBJ}/ssh2_config << EOF *: @@ -74,7 +73,7 @@ for v in ${VERSIONS}; do continue fi verbose "ssh2 ${v}" - key=ssh-dss + key=ssh-rsa skipcat=0 case $v in 2.1.*|2.3.0) @@ -124,7 +123,6 @@ for v in ${VERSIONS}; do done rm -rf ${OBJ}/${USER} -for i in ssh2_config random_seed dsa.pub dsa host.dsa \ - id.list id.com id.com.pub id.openssh; do +for i in ssh2_config random_seed id.list id.com id.com.pub id.openssh; do rm -f ${OBJ}/$i done diff --git a/regress/ssh-com.sh b/regress/ssh-com.sh index b1a2505..bb83338 100644 --- a/regress/ssh-com.sh +++ b/regress/ssh-com.sh @@ -1,4 +1,4 @@ -# $OpenBSD: ssh-com.sh,v 1.10 2017/05/08 01:52:49 djm Exp $ +# $OpenBSD: ssh-com.sh,v 1.11 2025/05/06 06:05:48 djm Exp $ # Placed in the Public Domain. tid="connect to ssh.com server" @@ -41,8 +41,8 @@ cat << EOF > $OBJ/sshd2_config PubKeyAuthentication yes #AllowedAuthentications publickey AuthorizationFile authorization - HostKeyFile ${SRC}/dsa_ssh2.prv - PublicHostKeyFile ${SRC}/dsa_ssh2.pub + HostKeyFile ${SRC}/rsa_ssh2.prv + PublicHostKeyFile ${SRC}/rsa_ssh2.pub RandomSeedFile ${OBJ}/random_seed MaxConnections 0 PermitRootLogin yes @@ -55,23 +55,21 @@ EOF sed "s/HostKeyAlias.*/HostKeyAlias ssh2-localhost-with-alias/" \ < $OBJ/ssh_config > $OBJ/ssh_config_com -# we need a DSA key for -rm -f ${OBJ}/dsa ${OBJ}/dsa.pub -${SSHKEYGEN} -q -N '' -t dsa -f ${OBJ}/dsa +# we need a RSA key for +rm -f ${OBJ}/rsa ${OBJ}/rsa.pub +${SSHKEYGEN} -q -N '' -t rsa -f ${OBJ}/rsa # setup userdir, try rsa first mkdir -p ${OBJ}/${USER} cp /dev/null ${OBJ}/${USER}/authorization -for t in rsa dsa; do - ${SSHKEYGEN} -e -f ${OBJ}/$t.pub > ${OBJ}/${USER}/$t.com - echo Key $t.com >> ${OBJ}/${USER}/authorization - echo IdentityFile ${OBJ}/$t >> ${OBJ}/ssh_config_com -done +${SSHKEYGEN} -e -f ${OBJ}/rsa.pub > ${OBJ}/${USER}/rsa.com +echo Key rsa.com >> ${OBJ}/${USER}/authorization +echo IdentityFile ${OBJ}/rsa >> ${OBJ}/ssh_config_com -# convert and append DSA hostkey +# convert and append RSA hostkey ( printf 'ssh2-localhost-with-alias,127.0.0.1,::1 ' - ${SSHKEYGEN} -if ${SRC}/dsa_ssh2.pub + ${SSHKEYGEN} -if ${SRC}/rsa_ssh2.pub ) >> $OBJ/known_hosts # go for it @@ -114,6 +112,6 @@ done rm -rf ${OBJ}/${USER} for i in sshd_config_proxy ssh_config_proxy random_seed \ - sshd2_config dsa.pub dsa ssh_config_com; do + sshd2_config rsa.pub rsa ssh_config_com; do rm -f ${OBJ}/$i done diff --git a/regress/ssh-pkcs11.sh b/regress/ssh-pkcs11.sh new file mode 100644 index 0000000..96680fc --- /dev/null +++ b/regress/ssh-pkcs11.sh @@ -0,0 +1,40 @@ +# $OpenBSD: ssh-pkcs11.sh,v 1.1 2025/10/16 00:01:54 djm Exp $ +# Placed in the Public Domain. + +tid="pkcs11 ssh test" + +p11_setup || skip "No PKCS#11 library found" + +grep -iv IdentityFile $OBJ/ssh_proxy | + grep -vi BatchMode > $OBJ/ssh_proxy.orig +#echo "IdentitiesOnly=yes" >> $OBJ/ssh_proxy.orig +echo "PKCS11Provider=${TEST_SSH_PKCS11}" >> $OBJ/ssh_proxy.orig + +check_all() { + tag="$1" + expect_success=$2 + pinsh="$3" + for k in $ED25519 $RSA $EC; do + kshort=`basename "$k"` + verbose "$tag: $kshort" + pub="$k.pub" + cp $pub $OBJ/key.pub + chmod 0600 $OBJ/key.pub + cat $OBJ/key.pub > $OBJ/authorized_keys_$USER + cp $OBJ/ssh_proxy.orig $OBJ/ssh_proxy + env SSH_ASKPASS="$pinsh" SSH_ASKPASS_REQUIRE=force \ + ${SSH} -F $OBJ/ssh_proxy somehost exit 5 >/dev/null 2>&1 + r=$? + if [ "x$expect_success" = "xy" ]; then + if [ $r -ne 5 ]; then + fail "ssh connect failed (exit code $r)" + fi + elif [ $r -eq 5 ]; then + fail "ssh connect succeeded unexpectedly (exit code $r)" + fi + done +} + +check_all "correct pin" y $PIN_SH +check_all "wrong pin" n $WRONGPIN_SH +check_all "nopin" n `which true` diff --git a/regress/ssh-tty.sh b/regress/ssh-tty.sh new file mode 100644 index 0000000..07053d1 --- /dev/null +++ b/regress/ssh-tty.sh @@ -0,0 +1,179 @@ +# $OpenBSD: ssh-tty.sh,v 1.8 2025/10/23 06:15:26 dtucker Exp $ +# Placed in the Public Domain. + +# Basic TTY smoke test + +tid="ssh-tty" + +# Fake home directory to avoid user shell configuration. +FAKEHOME="$OBJ/.fakehome" +rm -rf "$FAKEHOME" +mkdir -m 0700 -p "$FAKEHOME" + +case "${PATH}${HOME}" in +*\ *|*\t*) skip "\$PATH or \$HOME has whitespace, not supported in this test";; +esac + +# tmux stuff +TMUX=${TMUX:-tmux} +type $TMUX >/dev/null || skip "tmux not found" + +if $TMUX -V >/dev/null 2>&1; then + tver="`$TMUX -V 2>&1`" + echo "tmux version $tver" +else + skip "tmux version not reported" +fi + +CLEANENV="env -i HOME=$HOME LOGNAME=$USER USER=$USER PATH=$PATH SHELL=$SHELL" +TMUX_TEST="$CLEANENV $TMUX -f/dev/null -Lopenssh-regress-ssh-tty" +sess="regress-ssh-tty$$" + +# Multiplexing control socket. +CTL=$OBJ/ctl-sock + +# Some randomish strings used for signalling back and forth. +# We use the octal variants via printf(1). +MAGIC1="XY23zzY" +MAGIC1_OCTAL="\130\131\062\063\172\172\131" +MAGIC2="99sMarT86" +MAGIC2_OCTAL="\071\071\163\115\141\162\124\070\066" +MAGIC3="woLF1701d" +MAGIC3_OCTAL="\167\157\114\106\061\067\060\061\144" +MAGIC4="lUh4thX4evR" +MAGIC4_OCTAL="\154\125\150\064\164\150\130\064\145\166\122" +MAGIC5="AllMo1000x" +MAGIC5_OCTAL="\101\154\154\115\157\061\060\060\060\170" + +# Wait for a mux process to become ready. +wait_for_mux_ready() +{ + for i in 1 2 3 4 5 6 7 8 9; do + ${SSH} -F $OBJ/ssh_config -S $CTL -Ocheck otherhost \ + >/dev/null 2>&1 && return 0 + sleep $i + done + fatal "mux never becomes ready" +} + +# Wait for a mux process to have finished. +wait_for_mux_done() +{ + for i in 1 2 3 4 5 6 7 8 9; do + test -S $CTL || return 0 + sleep $i + done + fatal "mux socket never removed" +} + +# Wait for a regex to appear in terminal output. +wait_for_regex() { + string="$1" + errors_are_fatal="$2" + for x in 1 2 3 4 5 6 7 8 9 10 ; do + $TMUX_TEST capture-pane -pt $sess | grep "$string" >/dev/null + [ $? -eq 0 ] && return + sleep 1 + done + if test -z "$errors_are_fatal"; then + fail "failed to match \"$string\" in terminal output" + return + fi + fatal "failed to match \"$string\" in terminal output" +} + +# Check that a regex does *not* appear in terminal output +not_in_term() { + string="$1" + error="$2" + errors_are_fatal="$3" + $TMUX_TEST capture-pane -pt $sess | grep "$string" > /dev/null + [ $? -ne 0 ] && return + if test -z "$errors_are_fatal"; then + fail "$error" + return + fi + fatal "$error" +} + +# Shut down tmux session and Wait for it to terminate. +kill_tmux() { + $TMUX_TEST kill-session -t $sess 2>/dev/null + for x in 1 2 3 4 5 6 7 8 9 10; do + $TMUX_TEST has-session -t $sess >/dev/null 2>&1 || return + sleep 1 + done + fatal "tmux session didn't terminate" +} + +trap "$TMUX_TEST kill-session -t $sess 2>/dev/null" EXIT + +run_test() { + tag="$1" + ssh_args="$2" + # Prepare a tmux session. + kill_tmux + $TMUX_TEST new-session -d -s $sess + # echo XXXXXXXXXX $TMUX_TEST attach -t $sess; sleep 10 + + # Command to start SSH; sent as keystrokes to tmux session. + RCMD="$CLEANENV $SHELL" + CMD="$SSH -F $OBJ/ssh_proxy $ssh_args -S $CTL x -tt $RCMD" + + verbose "${tag}: start connection" + # arrange for the shell to print something after ssh completes. + $TMUX_TEST send-keys -t $sess "$CMD && printf '$MAGIC1_OCTAL\n'" ENTER + wait_for_mux_ready + + verbose "${tag}: send string" + $TMUX_TEST send-keys -t $sess "printf '$MAGIC2_OCTAL\n'" ENTER + wait_for_regex "$MAGIC2" + + verbose "${tag}: ^c interrupts process" + # ^c should interrupt the sleep and prevent the magic string + # from appearing. + $TMUX_TEST send-keys -t $sess \ + "printf '$MAGIC3_OCTAL' ; sleep 30 || printf '$MAGIC4_OCTAL\n'" + $TMUX_TEST send-keys -t $sess ENTER + wait_for_regex "$MAGIC3" # Command has executed. + $TMUX_TEST send-keys -t $sess "C-c" + # send another string to let us know that the sleep has finished. + $TMUX_TEST send-keys -t $sess "printf '$MAGIC5_OCTAL\n'" ENTER + wait_for_regex "$MAGIC5" + not_in_term "$MAGIC4" "^c did not interrupt" + + verbose "${tag}: ~? produces help" + $TMUX_TEST send-keys -t $sess ENTER "~?" + wait_for_regex "^Supported escape sequences:$" + + verbose "${tag}: ~. terminates session" + $TMUX_TEST send-keys -t $sess ENTER "~." + wait_for_mux_done + not_in_term "$MAGIC1" "ssh unexpectedly exited successfully after ~." + + verbose "${tag}: restart session" + $TMUX_TEST send-keys -t $sess "$CMD && printf '$MAGIC1_OCTAL\n'" ENTER + wait_for_mux_ready + + verbose "${tag}: eof terminates session successfully" + $TMUX_TEST send-keys -t $sess ENTER "C-d" + wait_for_regex "$MAGIC1" +} + +# Make sure tmux is working as expected before we start. +kill_tmux +$TMUX_TEST new-session -d -s $sess +# Make sure the session doesn't contain the magic strings we will use +# for signalling or any #? output. +not_in_term "$MAGIC1" "terminal already contains magic1 string" fatal +not_in_term "$MAGIC2" "terminal already contains magic2 string" fatal +not_in_term "$MAGIC3" "terminal already contains magic3 string" fatal +not_in_term "$MAGIC4" "terminal already contains magic4 string" fatal +not_in_term "$MAGIC5" "terminal already contains magic5 string" fatal +not_in_term "^Supported escape" "terminal already contains escape help" fatal +$TMUX_TEST send-keys -t $sess "printf '$MAGIC1_OCTAL\n'" ENTER +wait_for_regex "$MAGIC1" fatal +kill_tmux + +run_test "basic" "-oControlMaster=yes" +run_test "ControlPersist" "-oControlMaster=auto -oControlPersist=1s" diff --git a/regress/ssh2putty.sh b/regress/ssh2putty.sh index 9b08310..bd29131 100755 --- a/regress/ssh2putty.sh +++ b/regress/ssh2putty.sh @@ -1,5 +1,5 @@ #!/bin/sh -# $OpenBSD: ssh2putty.sh,v 1.9 2021/07/25 12:13:03 dtucker Exp $ +# $OpenBSD: ssh2putty.sh,v 1.10 2025/05/06 06:05:48 djm Exp $ if test "x$1" = "x" -o "x$2" = "x" -o "x$3" = "x" ; then echo "Usage: ssh2putty hostname port ssh-private-key" @@ -12,7 +12,6 @@ KEYFILE=$3 OPENSSL_BIN="${OPENSSL_BIN:-openssl}" -# XXX - support DSA keys too if grep "BEGIN RSA PRIVATE KEY" $KEYFILE >/dev/null 2>&1 ; then : else diff --git a/regress/sshcfgparse.sh b/regress/sshcfgparse.sh index 504853d..29fa1d8 100644 --- a/regress/sshcfgparse.sh +++ b/regress/sshcfgparse.sh @@ -1,15 +1,8 @@ -# $OpenBSD: sshcfgparse.sh,v 1.9 2021/06/08 07:05:27 dtucker Exp $ +# $OpenBSD: sshcfgparse.sh,v 1.10 2025/05/06 06:05:48 djm Exp $ # Placed in the Public Domain. tid="ssh config parse" -dsa=0 -for t in $SSH_KEYTYPES; do - case "$t" in - ssh-dss) dsa=1 ;; - esac -done - expect_result_present() { _str="$1" ; shift for _expect in "$@" ; do @@ -66,33 +59,23 @@ verbose "pubkeyacceptedalgorithms" # Default set f=`${SSH} -GF none host | awk '/^pubkeyacceptedalgorithms /{print $2}'` expect_result_present "$f" "ssh-ed25519" "ssh-ed25519-cert-v01.*" -expect_result_absent "$f" "ssh-dss" # Explicit override f=`${SSH} -GF none -opubkeyacceptedalgorithms=ssh-ed25519 host | \ awk '/^pubkeyacceptedalgorithms /{print $2}'` expect_result_present "$f" "ssh-ed25519" -expect_result_absent "$f" "ssh-ed25519-cert-v01.*" "ssh-dss" +expect_result_absent "$f" "ssh-ed25519-cert-v01.*" # Removal from default set f=`${SSH} -GF none -opubkeyacceptedalgorithms=-ssh-ed25519-cert* host | \ awk '/^pubkeyacceptedalgorithms /{print $2}'` expect_result_present "$f" "ssh-ed25519" -expect_result_absent "$f" "ssh-ed25519-cert-v01.*" "ssh-dss" +expect_result_absent "$f" "ssh-ed25519-cert-v01.*" f=`${SSH} -GF none -opubkeyacceptedalgorithms=-ssh-ed25519 host | \ awk '/^pubkeyacceptedalgorithms /{print $2}'` expect_result_present "$f" "ssh-ed25519-cert-v01.*" -expect_result_absent "$f" "ssh-ed25519" "ssh-dss" +expect_result_absent "$f" "ssh-ed25519" # Append to default set. # This is not tested when built !WITH_OPENSSL -if [ "$dsa" = "1" ]; then - f=`${SSH} -GF none -opubkeyacceptedalgorithms=+ssh-dss-cert* host | \ - awk '/^pubkeyacceptedalgorithms /{print $2}'` - expect_result_present "$f" "ssh-ed25519" "ssh-dss-cert-v01.*" - expect_result_absent "$f" "ssh-dss" - f=`${SSH} -GF none -opubkeyacceptedalgorithms=+ssh-dss host | \ - awk '/^pubkeyacceptedalgorithms /{print $2}'` - expect_result_present "$f" "ssh-ed25519" "ssh-ed25519-cert-v01.*" "ssh-dss" - expect_result_absent "$f" "ssh-dss-cert-v01.*" -fi +# XXX need a test for this verbose "agentforwarding" f=`${SSH} -GF none host | awk '/^forwardagent /{print$2}'` diff --git a/regress/sshfp-connect.sh b/regress/sshfp-connect.sh index f786469..3c73a35 100644 --- a/regress/sshfp-connect.sh +++ b/regress/sshfp-connect.sh @@ -1,4 +1,4 @@ -# $OpenBSD: sshfp-connect.sh,v 1.4 2021/09/01 00:50:27 dtucker Exp $ +# $OpenBSD: sshfp-connect.sh,v 1.5 2025/03/11 11:46:44 dtucker Exp $ # Placed in the Public Domain. # This test requires external setup and thus is skipped unless @@ -29,6 +29,12 @@ if ! $SSH -Q key-plain | grep ssh-rsa >/dev/null; then elif [ -z "${TEST_SSH_SSHFP_DOMAIN}" ]; then skip "TEST_SSH_SSHFP_DOMAIN not set." else + # Prime any DNS caches and resolvers. + for i in sshtest sshtest-sha1 sshtest-sha256; do + host -t sshfp ${i}.${TEST_SSH_SSHFP_DOMAIN} >/dev/null 2>&1 + host -t sshfp ${i}-bad.${TEST_SSH_SSHFP_DOMAIN} >/dev/null 2>&1 + done + # Set RSA host key to match fingerprints above. mv $OBJ/sshd_proxy $OBJ/sshd_proxy.orig $SUDO cp $SRC/rsa_openssh.prv $OBJ/host.ssh-rsa diff --git a/regress/sshsig.sh b/regress/sshsig.sh index dae0370..fe0958a 100644 --- a/regress/sshsig.sh +++ b/regress/sshsig.sh @@ -1,4 +1,4 @@ -# $OpenBSD: sshsig.sh,v 1.15 2023/10/12 03:51:08 djm Exp $ +# $OpenBSD: sshsig.sh,v 1.16 2025/09/11 07:23:32 djm Exp $ # Placed in the Public Domain. tid="sshsig" @@ -255,7 +255,7 @@ for t in $SIGNKEYS; do # Check signing keys using ssh-agent. trace "$tid: key type $t prepare agent" ${SSHADD} -D >/dev/null 2>&1 # Remove all previously-loaded keys. - ${SSHADD} ${privkey} > /dev/null 2>&1 || fail "ssh-add failed" + ${SSHADD} -N ${privkey} > /dev/null 2>&1 || fail "ssh-add failed" # Move private key to ensure agent key is used mv ${privkey} ${privkey}.tmp diff --git a/regress/test-exec.sh b/regress/test-exec.sh index 7afc280..577bc01 100644 --- a/regress/test-exec.sh +++ b/regress/test-exec.sh @@ -1,4 +1,4 @@ -# $OpenBSD: test-exec.sh,v 1.119 2024/06/20 08:18:34 dtucker Exp $ +# $OpenBSD: test-exec.sh,v 1.139 2025/12/22 01:31:07 djm Exp $ # Placed in the Public Domain. #SUDO=sudo @@ -91,6 +91,7 @@ SSHKEYSCAN=ssh-keyscan SFTP=sftp SFTPSERVER=/usr/libexec/openssh/sftp-server SSHD_SESSION=/usr/libexec/sshd-session +SSHD_AUTH=/usr/libexec/sshd-auth SCP=scp # Set by make_tmpdir() on demand (below). @@ -100,7 +101,7 @@ SSH_REGRESS_TMP= PLINK=/usr/local/bin/plink PUTTYGEN=/usr/local/bin/puttygen CONCH=/usr/local/bin/conch -DROPBEAR=/usr/local/bin/dropbear +DROPBEAR=/usr/local/sbin/dropbear DBCLIENT=/usr/local/bin/dbclient DROPBEARKEY=/usr/local/bin/dropbearkey DROPBEARCONVERT=/usr/local/bin/dropbearconvert @@ -119,6 +120,9 @@ fi if [ "x$TEST_SSH_SSHD_SESSION" != "x" ]; then SSHD_SESSION="${TEST_SSH_SSHD_SESSION}" fi +if [ "x$TEST_SSH_SSHD_AUTH" != "x" ]; then + SSHD_AUTH="${TEST_SSH_SSHD_AUTH}" +fi if [ "x$TEST_SSH_SSHD" != "x" ]; then SSHD="${TEST_SSH_SSHD}" fi @@ -164,6 +168,9 @@ fi if [ "x$TEST_SSH_DROPBEARCONVERT" != "x" ]; then DROPBEARCONVERT="${TEST_SSH_DROPBEARCONVERT}" fi +if [ "x$TEST_SSH_TMUX" != "x" ]; then + TMUX="${TEST_SSH_TMUX}" +fi if [ "x$TEST_SSH_PKCS11_HELPER" != "x" ]; then SSH_PKCS11_HELPER="${TEST_SSH_PKCS11_HELPER}" fi @@ -180,6 +187,11 @@ case "$SSHD" in *) SSHD=`which $SSHD` ;; esac +case "$SSH" in +/*) ;; +*) SSH=`which $SSH` ;; +esac + case "$SSHAGENT" in /*) ;; *) SSHAGENT=`which $SSHAGENT` ;; @@ -305,6 +317,7 @@ fi # to preserve our debug logging. In the rare instance where -q is desirable # -qq is equivalent and is not removed. SSHLOGWRAP=$OBJ/ssh-log-wrapper.sh +rm -f ${SSHLOGWRAP} cat >$SSHLOGWRAP <$SSHDLOGWRAP <>$TEST_REGRESS_LOGFILE @@ -531,19 +547,6 @@ save_debug_log () (cat $TEST_REGRESS_LOGFILE; echo) >>$OBJ/failed-regress.log (cat $TEST_SSH_LOGFILE; echo) >>$OBJ/failed-ssh.log (cat $TEST_SSHD_LOGFILE; echo) >>$OBJ/failed-sshd.log - - # Save all logfiles in a tarball. - (cd $OBJ && - logfiles="" - for i in $TEST_REGRESS_LOGFILE $TEST_SSH_LOGFILE $TEST_SSHD_LOGFILE \ - $TEST_SSH_LOGDIR; do - if [ -e "`basename $i`" ]; then - logfiles="$logfiles `basename $i`" - else - logfiles="$logfiles $i" - fi - done - tar cf "$tarname" $logfiles) } trace () @@ -621,6 +624,7 @@ cat << EOF > $OBJ/sshd_config AcceptEnv _XXX_TEST Subsystem sftp $SFTPSERVER SshdSessionPath $SSHD_SESSION + SshdAuthPath $SSHD_AUTH PerSourcePenalties no EOF @@ -718,9 +722,9 @@ export EXTRA_AGENT_ARGS maybe_filter_sk() { if test -z "$SSH_SK_PROVIDER" ; then - grep -v ^sk + grep -v ^sk | grep -v ^webauthn else - cat + grep -v ^webauthn fi } @@ -845,7 +849,8 @@ esac if test "$REGRESS_INTEROP_DROPBEAR" = "yes" ; then trace Create dropbear keys and add to authorized_keys - mkdir -p $OBJ/.dropbear + mkdir -p $OBJ/.dropbear $OBJ/.ssh + awk '{print "somehost "$2" "$3}' $OBJ/known_hosts >$OBJ/.ssh/known_hosts kt="ed25519" for i in dss rsa ecdsa; do if $SSH -Q key-plain | grep "$i" >/dev/null; then @@ -871,7 +876,7 @@ fi # create a proxy version of the client config ( cat $OBJ/ssh_config - echo proxycommand ${SUDO} env SSH_SK_HELPER=\"$SSH_SK_HELPER\" ${OBJ}/sshd-log-wrapper.sh -i -f $OBJ/sshd_proxy + echo proxycommand ${SUDO} env SSH_SK_HELPER=\"$SSH_SK_HELPER\" ${TEST_SSH_SSHD_ENV} ${OBJ}/sshd-log-wrapper.sh -i -f $OBJ/sshd_proxy ) > $OBJ/ssh_proxy # check proxy config @@ -888,8 +893,9 @@ start_sshd () PIDFILE=$OBJ/pidfile # start sshd logfile="${TEST_SSH_LOGDIR}/sshd.`$OBJ/timestamp`.$$.log" - $SUDO ${SSHD} -f $OBJ/sshd_config "$@" -t || fatal "sshd_config broken" - $SUDO env SSH_SK_HELPER="$SSH_SK_HELPER" \ + $SUDO env SSH_SK_HELPER="$SSH_SK_HELPER" ${TEST_SSH_SSHD_ENV} \ + ${SSHD} -f $OBJ/sshd_config "$@" -t || fatal "sshd_config broken" + $SUDO env SSH_SK_HELPER="$SSH_SK_HELPER" ${TEST_SSH_SSHD_ENV} \ ${SSHD} -f $OBJ/sshd_config "$@" -E$TEST_SSHD_LOGFILE trace "wait for sshd" @@ -898,11 +904,18 @@ start_sshd () i=`expr $i + 1` sleep $i done + rm -f ${TEST_SSHD_LOGFILE} ln -f -s ${logfile} $TEST_SSHD_LOGFILE test -f $PIDFILE || fatal "no sshd running on port $PORT" } +enable_all_kexes_in_sshd () +{ + kexs=`$SSH -Q KexAlgorithms | (tr '\n' ,; echo) | sed 's/,$//'` + echo KexAlgorithms $kexs >>$OBJ/sshd_config +} + # Find a PKCS#11 library. p11_find_lib() { TEST_SSH_PKCS11="" @@ -919,12 +932,15 @@ p11_find_lib() { PKCS11_OK= export PKCS11_OK p11_setup() { + # XXX we could potentially test ed25519 only in the absence of + # RSA and ECDSA support. + $SSH -Q key | grep ssh-rsa >/dev/null || return 1 p11_find_lib \ /usr/local/lib/softhsm/libsofthsm2.so \ /usr/lib64/pkcs11/libsofthsm2.so \ /usr/lib/x86_64-linux-gnu/softhsm/libsofthsm2.so test -z "$TEST_SSH_PKCS11" && return 1 - verbose "using token library $TEST_SSH_PKCS11" + trace "using token library $TEST_SSH_PKCS11" TEST_SSH_PIN=1234 TEST_SSH_SOPIN=12345678 if [ "x$TEST_SSH_SSHPKCS11HELPER" != "x" ]; then @@ -961,7 +977,7 @@ EOF softhsm2-util --slot "$slot" --label 01 --id 01 --pin "$TEST_SSH_PIN" \ --import $RSAP8 >/dev/null || fatal "softhsm import RSA fail" chmod 600 $RSA - ssh-keygen -y -f $RSA > ${RSA}.pub + ${SSHKEYGEN} -y -f $RSA > ${RSA}.pub # ECDSA key ECPARAM=${SSH_SOFTHSM_DIR}/ECPARAM EC=${SSH_SOFTHSM_DIR}/EC @@ -975,16 +991,38 @@ EOF softhsm2-util --slot "$slot" --label 02 --id 02 --pin "$TEST_SSH_PIN" \ --import $ECP8 >/dev/null || fatal "softhsm import EC fail" chmod 600 $EC - ssh-keygen -y -f $EC > ${EC}.pub - # Prepare askpass script to load PIN. + ${SSHKEYGEN} -y -f $EC > ${EC}.pub + # Ed25519 key + ED25519=${SSH_SOFTHSM_DIR}/ED25519 + ED25519P8=${SSH_SOFTHSM_DIR}/ED25519P8 + $OPENSSL_BIN genpkey -algorithm ed25519 > $ED25519 || \ + fatal "genpkey Ed25519 fail" + $OPENSSL_BIN pkcs8 -nocrypt -in $ED25519 > $ED25519P8 || \ + fatal "pkcs8 Ed25519 fail" + softhsm2-util --slot "$slot" --label 03 --id 03 --pin "$TEST_SSH_PIN" \ + --import $ED25519P8 >/dev/null || \ + fatal "softhsm import ed25519 fail" + chmod 600 $ED25519 + ${SSHKEYGEN} -y -f $ED25519 > ${ED25519}.pub + # Prepare some askpass scripts to load PINs. PIN_SH=$SSH_SOFTHSM_DIR/pin.sh cat > $PIN_SH << EOF #!/bin/sh echo "${TEST_SSH_PIN}" EOF chmod 0700 "$PIN_SH" + WRONGPIN_SH=$SSH_SOFTHSM_DIR/wrongpin.sh + cat > $WRONGPIN_SH << EOF +#!/bin/sh +echo "0000" +EOF + chmod 0700 "$WRONGPIN_SH" PKCS11_OK=yes - return 0 + if env SSH_ASKPASS="$PIN_SH" SSH_ASKPASS_REQUIRE=force \ + ${SSHKEYGEN} -D ${TEST_SSH_PKCS11} >/dev/null 2>&1 ; then + return 0 + fi + return 1 } # Peforms ssh-add with the right token PIN. @@ -992,6 +1030,31 @@ p11_ssh_add() { env SSH_ASKPASS="$PIN_SH" SSH_ASKPASS_REQUIRE=force ${SSHADD} "$@" } +start_ssh_agent() { + EXTRA_AGENT_ARGS="$1" + if [ "$PKCS11_OK" = "yes" ]; then + EXTRA_AGENT_ARGS="${EXTRA_AGENT_ARGS} -P${TEST_SSH_PKCS11}" + fi + SSH_AUTH_SOCK="$OBJ/agent.sock" + export SSH_AUTH_SOCK + rm -f $SSH_AUTH_SOCK $OBJ/agent.log + trace "start agent" + ${SSHAGENT} ${EXTRA_AGENT_ARGS} -d -a $SSH_AUTH_SOCK \ + > $OBJ/agent.log 2>&1 & + AGENT_PID=$! + trap "kill $AGENT_PID" EXIT + for x in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ; do + # Give it a chance to start + ${SSHADD} -l > /dev/null 2>&1 + r=$? + test $r -eq 1 && break + sleep 1 + done + if [ $r -ne 1 ]; then + fatal "ssh-add -l did not fail with exit code 1 (got $r)" + fi +} + # source test body . $SCRIPT diff --git a/regress/unittests/Makefile.inc b/regress/unittests/Makefile.inc index 98e2804..a5c2e8c 100644 --- a/regress/unittests/Makefile.inc +++ b/regress/unittests/Makefile.inc @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile.inc,v 1.16 2024/01/11 01:45:58 djm Exp $ +# $OpenBSD: Makefile.inc,v 1.19 2025/10/23 19:06:10 miod Exp $ .include .include @@ -7,6 +7,9 @@ UNITTEST_FAST?= no # Skip slow tests (e.g. less intensive fuzzing). UNITTEST_SLOW?= no # Include slower tests (e.g. more intensive fuzzing). UNITTEST_VERBOSE?= no # Verbose test output (inc. per-test names). +UNITTEST_BENCHMARK?= no # Run unit tests in benchmarking mode. +UNITTEST_BENCH_DETAIL?=no # Detailed benchmark statistics. +UNITTEST_BENCH_ONLY?= # Run only these benchmarks MALLOC_OPTIONS?= CFGJRSUX TEST_ENV?= MALLOC_OPTIONS=${MALLOC_OPTIONS} @@ -15,10 +18,6 @@ TEST_ENV?= MALLOC_OPTIONS=${MALLOC_OPTIONS} OPENSSL?= yes DSAKEY?= yes -.if (${DSAKEY:L} == "yes") -CFLAGS+= -DWITH_DSA -.endif - .if (${OPENSSL:L} == "yes") CFLAGS+= -DWITH_OPENSSL .endif @@ -39,6 +38,7 @@ CDIAGFLAGS+= -Wimplicit CDIAGFLAGS+= -Winline CDIAGFLAGS+= -Wmissing-declarations CDIAGFLAGS+= -Wmissing-prototypes +CDIAGFLAGS+= -Wold-style-definition CDIAGFLAGS+= -Wparentheses CDIAGFLAGS+= -Wpointer-arith CDIAGFLAGS+= -Wreturn-type @@ -51,9 +51,6 @@ CDIAGFLAGS+= -Wtrigraphs CDIAGFLAGS+= -Wuninitialized CDIAGFLAGS+= -Wunused CDIAGFLAGS+= -Wno-unused-parameter -.if ${COMPILER_VERSION:L} != "gcc3" -CDIAGFLAGS+= -Wold-style-definition -.endif SSHREL=../../../../../usr.bin/ssh @@ -69,8 +66,8 @@ DPADD+=${.CURDIR}/../test_helper/libtest_helper.a .PATH: ${.CURDIR}/${SSHREL} -LDADD+= -lutil -DPADD+= ${LIBUTIL} +LDADD+= -lutil -lm +DPADD+= ${LIBUTIL} ${LIBM} .if (${OPENSSL:L} == "yes") LDADD+= -lcrypto @@ -82,11 +79,21 @@ DPADD+= ${LIBFIDO2} ${LIBCBOR} ${LIBUSBHID} UNITTEST_ARGS?= -.if (${UNITTEST_VERBOSE:L} != "no") +.if (${UNITTEST_VERBOSE:L:R} != "no") UNITTEST_ARGS+= -v .endif -.if (${UNITTEST_FAST:L} != "no") +.if (${UNITTEST_FAST:L:R} != "no") UNITTEST_ARGS+= -f -.elif (${UNITTEST_SLOW:L} != "no") +.elif (${UNITTEST_SLOW:L:R} != "no") UNITTEST_ARGS+= -F .endif + +.if (${UNITTEST_BENCHMARK:L:R} != "no") +UNITTEST_ARGS+= -b +.endif +.if (${UNITTEST_BENCH_DETAIL:L:R} != "no") +UNITTEST_ARGS+= -B +.endif +.if (${UNITTEST_BENCH_ONLY:L} != "") +UNITTEST_ARGS+= -O "${UNITTEST_BENCH_ONLY}" +.endif diff --git a/regress/unittests/authopt/Makefile b/regress/unittests/authopt/Makefile index 3045ec7..a7b8a86 100644 --- a/regress/unittests/authopt/Makefile +++ b/regress/unittests/authopt/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.7 2023/01/15 23:35:10 djm Exp $ +# $OpenBSD: Makefile,v 1.12 2026/02/06 23:39:14 dtucker Exp $ PROG=test_authopt SRCS=tests.c @@ -8,20 +8,20 @@ SRCS+=auth-options.c # From usr.bin/ssh SRCS+=sshbuf-getput-basic.c sshbuf-getput-crypto.c sshbuf-misc.c sshbuf.c SRCS+=sshbuf-io.c atomicio.c sshkey.c authfile.c cipher.c log.c ssh-rsa.c -SRCS+=ssh-dss.c ssh-ecdsa.c ssh-ed25519.c mac.c umac.c umac128.c hmac.c misc.c +SRCS+=ssh-ecdsa.c ssh-ed25519.c mac.c umac.c umac128.c hmac.c misc.c SRCS+=ssherr.c uidswap.c cleanup.c xmalloc.c match.c krl.c fatal.c SRCS+=addr.c addrmatch.c bitmap.c -SRCS+=ed25519.c hash.c SRCS+=cipher-chachapoly.c chacha.c poly1305.c ssh-ecdsa-sk.c ssh-sk.c -SRCS+=ssh-ed25519-sk.c sk-usbhid.c +SRCS+=ssh-ed25519-sk.c sk-usbhid.c ssh-pkcs11-client.c +SRCS+=ssherr-libcrypto.c -SRCS+=digest-openssl.c -#SRCS+=digest-libc.c +SRCS+=digest-openssl.c ed25519-openssl.c +#SRCS+=digest-libc.c ed25519.c SRCS+=utf8.c REGRESS_TARGETS=run-regress-${PROG} run-regress-${PROG}: ${PROG} - env ${TEST_ENV} ./${PROG} -d ${.CURDIR}/testdata + env ${TEST_ENV} ./${PROG} ${UNITTEST_ARGS} -d ${.CURDIR}/testdata .include diff --git a/regress/unittests/authopt/tests.c b/regress/unittests/authopt/tests.c index d9e1903..2376b47 100644 --- a/regress/unittests/authopt/tests.c +++ b/regress/unittests/authopt/tests.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tests.c,v 1.3 2021/12/14 21:25:27 deraadt Exp $ */ +/* $OpenBSD: tests.c,v 1.5 2025/11/20 05:07:57 dtucker Exp $ */ /* * Regress test for keys options functions. @@ -10,9 +10,7 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include @@ -143,6 +141,7 @@ test_authkeys_parse(void) opts = sshauthopt_parse(keywords, &errstr); \ ASSERT_PTR_EQ(opts, NULL); \ ASSERT_PTR_NE(errstr, NULL); \ + sshauthopt_free(opts); \ TEST_DONE(); \ } while (0) #define CHECK_SUCCESS_AND_CLEANUP() \ @@ -576,3 +575,9 @@ tests(void) test_cert_parse(); test_merge(); } + +void +benchmarks(void) +{ + printf("no benchmarks\n"); +} diff --git a/regress/unittests/bitmap/Makefile b/regress/unittests/bitmap/Makefile index fe30acc..22bc00c 100644 --- a/regress/unittests/bitmap/Makefile +++ b/regress/unittests/bitmap/Makefile @@ -1,14 +1,16 @@ -# $OpenBSD: Makefile,v 1.4 2017/12/21 00:41:22 djm Exp $ +# $OpenBSD: Makefile,v 1.6 2026/02/06 23:39:14 dtucker Exp $ PROG=test_bitmap SRCS=tests.c # From usr.sbin/ssh -SRCS+=bitmap.c atomicio.c +SRCS+=bitmap.c atomicio.c misc.c xmalloc.c fatal.c log.c cleanup.c match.c +SRCS+=sshbuf.c sshbuf-getput-basic.c sshbuf-misc.c ssherr.c addr.c addrmatch.c +SRCS+=ssherr-libcrypto.c REGRESS_TARGETS=run-regress-${PROG} run-regress-${PROG}: ${PROG} - env ${TEST_ENV} ./${PROG} + env ${TEST_ENV} ./${PROG} ${UNITTEST_ARGS} .include diff --git a/regress/unittests/bitmap/tests.c b/regress/unittests/bitmap/tests.c index 576b863..6470f98 100644 --- a/regress/unittests/bitmap/tests.c +++ b/regress/unittests/bitmap/tests.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tests.c,v 1.2 2021/12/14 21:25:27 deraadt Exp $ */ +/* $OpenBSD: tests.c,v 1.3 2025/04/15 04:00:42 djm Exp $ */ /* * Regress test for bitmap.h bitmap API * @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include @@ -23,7 +21,7 @@ #include "bitmap.h" -#define NTESTS 131 +#define DEFAULT_NTESTS 131 void tests(void) @@ -32,10 +30,15 @@ tests(void) struct bitmap *b; BIGNUM *bn; size_t len; - int i, j, k, n; + int i, j, k, n, ntests = DEFAULT_NTESTS; u_char bbuf[1024], bnbuf[1024]; int r; + if (test_is_fast()) + ntests /= 4; + else if (test_is_slow()) + ntests *= 2; + TEST_START("bitmap_new"); b = bitmap_new(); ASSERT_PTR_NE(b, NULL); @@ -44,9 +47,9 @@ tests(void) TEST_DONE(); TEST_START("bitmap_set_bit / bitmap_test_bit"); - for (i = -1; i < NTESTS; i++) { - for (j = -1; j < NTESTS; j++) { - for (k = -1; k < NTESTS; k++) { + for (i = -1; i < ntests; i++) { + for (j = -1; j < ntests; j++) { + for (k = -1; k < ntests; k++) { bitmap_zero(b); BN_clear(bn); @@ -67,7 +70,7 @@ tests(void) /* Check perfect match between bitmap and bn */ test_subtest_info("match %d/%d/%d", i, j, k); - for (n = 0; n < NTESTS; n++) { + for (n = 0; n < ntests; n++) { ASSERT_INT_EQ(BN_is_bit_set(bn, n), bitmap_test_bit(b, n)); } @@ -99,7 +102,7 @@ tests(void) bitmap_zero(b); ASSERT_INT_EQ(bitmap_from_string(b, bnbuf, len), 0); - for (n = 0; n < NTESTS; n++) { + for (n = 0; n < ntests; n++) { ASSERT_INT_EQ(BN_is_bit_set(bn, n), bitmap_test_bit(b, n)); } @@ -107,7 +110,7 @@ tests(void) /* Test clearing bits */ test_subtest_info("clear %d/%d/%d", i, j, k); - for (n = 0; n < NTESTS; n++) { + for (n = 0; n < ntests; n++) { ASSERT_INT_EQ(bitmap_set_bit(b, n), 0); ASSERT_INT_EQ(BN_set_bit(bn, n), 1); } @@ -123,7 +126,7 @@ tests(void) bitmap_clear_bit(b, k); BN_clear_bit(bn, k); } - for (n = 0; n < NTESTS; n++) { + for (n = 0; n < ntests; n++) { ASSERT_INT_EQ(BN_is_bit_set(bn, n), bitmap_test_bit(b, n)); } @@ -135,4 +138,9 @@ tests(void) TEST_DONE(); #endif } +void +benchmarks(void) +{ + printf("no benchmarks\n"); +} diff --git a/regress/unittests/conversion/Makefile b/regress/unittests/conversion/Makefile index 5793c49..93dffa5 100644 --- a/regress/unittests/conversion/Makefile +++ b/regress/unittests/conversion/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.4 2021/01/09 12:24:30 dtucker Exp $ +# $OpenBSD: Makefile,v 1.6 2026/02/06 23:39:14 dtucker Exp $ PROG=test_conversion SRCS=tests.c @@ -6,11 +6,11 @@ SRCS=tests.c # From usr.bin/ssh SRCS+=sshbuf-getput-basic.c sshbuf-getput-crypto.c sshbuf-misc.c sshbuf.c SRCS+=atomicio.c misc.c xmalloc.c log.c uidswap.c cleanup.c fatal.c ssherr.c -SRCS+=match.c addr.c addrmatch.c +SRCS+=match.c addr.c addrmatch.c ssherr-libcrypto.c REGRESS_TARGETS=run-regress-${PROG} run-regress-${PROG}: ${PROG} - env ${TEST_ENV} ./${PROG} + env ${TEST_ENV} ./${PROG} ${UNITTEST_ARGS} .include diff --git a/regress/unittests/conversion/tests.c b/regress/unittests/conversion/tests.c index 5b526f7..fce4d1c 100644 --- a/regress/unittests/conversion/tests.c +++ b/regress/unittests/conversion/tests.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tests.c,v 1.4 2021/12/14 21:25:27 deraadt Exp $ */ +/* $OpenBSD: tests.c,v 1.5 2025/04/15 04:00:42 djm Exp $ */ /* * Regress test for conversions * @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include @@ -50,3 +48,9 @@ tests(void) ASSERT_INT_EQ(convtime("1000000000000000000000w"), -1); TEST_DONE(); } + +void +benchmarks(void) +{ + printf("no benchmarks\n"); +} diff --git a/regress/unittests/hostkeys/Makefile b/regress/unittests/hostkeys/Makefile index 04d9335..2e154e1 100644 --- a/regress/unittests/hostkeys/Makefile +++ b/regress/unittests/hostkeys/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.10 2023/01/15 23:35:10 djm Exp $ +# $OpenBSD: Makefile,v 1.15 2026/02/06 23:39:14 dtucker Exp $ PROG=test_hostkeys SRCS=tests.c test_iterate.c @@ -6,20 +6,19 @@ SRCS=tests.c test_iterate.c # From usr.bin/ssh SRCS+=sshbuf-getput-basic.c sshbuf-getput-crypto.c sshbuf-misc.c sshbuf.c SRCS+=sshbuf-io.c atomicio.c sshkey.c authfile.c cipher.c log.c ssh-rsa.c -SRCS+=ssh-dss.c ssh-ecdsa.c ssh-ed25519.c mac.c umac.c umac128.c hmac.c misc.c +SRCS+=ssh-ecdsa.c ssh-ed25519.c mac.c umac.c umac128.c hmac.c misc.c SRCS+=ssherr.c uidswap.c cleanup.c xmalloc.c match.c krl.c fatal.c SRCS+=addr.c addrmatch.c bitmap.c hostfile.c -SRCS+=ed25519.c hash.c SRCS+=cipher-chachapoly.c chacha.c poly1305.c ssh-ecdsa-sk.c ssh-sk.c -SRCS+=ssh-ed25519-sk.c sk-usbhid.c +SRCS+=ssh-ed25519-sk.c sk-usbhid.c ssh-pkcs11-client.c ssherr-libcrypto.c -SRCS+=digest-openssl.c -#SRCS+=digest-libc.c +SRCS+=digest-openssl.c ed25519-openssl.c +#SRCS+=digest-libc.c ed25519.c SRCS+=utf8.c REGRESS_TARGETS=run-regress-${PROG} run-regress-${PROG}: ${PROG} - env ${TEST_ENV} ./${PROG} -d ${.CURDIR}/testdata + env ${TEST_ENV} ./${PROG} ${UNITTEST_ARGS} -d ${.CURDIR}/testdata .include diff --git a/regress/unittests/hostkeys/mktestdata.sh b/regress/unittests/hostkeys/mktestdata.sh index 5a46de9..5fec582 100644 --- a/regress/unittests/hostkeys/mktestdata.sh +++ b/regress/unittests/hostkeys/mktestdata.sh @@ -1,11 +1,11 @@ #!/bin/sh -# $OpenBSD: mktestdata.sh,v 1.2 2017/04/30 23:33:48 djm Exp $ +# $OpenBSD: mktestdata.sh,v 1.3 2025/05/06 06:05:48 djm Exp $ set -ex cd testdata -rm -f rsa* dsa* ecdsa* ed25519* +rm -f rsa* ecdsa* ed25519* rm -f known_hosts* gen_all() { @@ -14,11 +14,10 @@ gen_all() { test "x$_n" = "x1" && _ecdsa_bits=384 test "x$_n" = "x2" && _ecdsa_bits=521 ssh-keygen -qt rsa -b 1024 -C "RSA #$_n" -N "" -f rsa_$_n - ssh-keygen -qt dsa -b 1024 -C "DSA #$_n" -N "" -f dsa_$_n ssh-keygen -qt ecdsa -b $_ecdsa_bits -C "ECDSA #$_n" -N "" -f ecdsa_$_n ssh-keygen -qt ed25519 -C "ED25519 #$_n" -N "" -f ed25519_$_n # Don't need private keys - rm -f rsa_$_n dsa_$_n ecdsa_$_n ed25519_$_n + rm -f rsa_$_n ecdsa_$_n ed25519_$_n } hentries() { @@ -65,18 +64,18 @@ rm -f known_hosts_hash_frag.old echo "# Revoked and CA keys" printf "@revoked sisyphus.example.com " ; cat ed25519_4.pub printf "@cert-authority prometheus.example.com " ; cat ecdsa_4.pub - printf "@cert-authority *.example.com " ; cat dsa_4.pub + printf "@cert-authority *.example.com " ; cat rsa_4.pub printf "\n" echo "# Some invalid lines" # Invalid marker - printf "@what sisyphus.example.com " ; cat dsa_1.pub + printf "@what sisyphus.example.com " ; cat rsa_1.pub # Key missing echo "sisyphus.example.com " # Key blob missing echo "prometheus.example.com ssh-ed25519 " # Key blob truncated - echo "sisyphus.example.com ssh-dsa AAAATgAAAAdz" + echo "sisyphus.example.com ssh-rsa AAAATgAAAAdz" # Invalid type echo "sisyphus.example.com ssh-XXX AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg==" # Type mismatch with blob diff --git a/regress/unittests/hostkeys/test_iterate.c b/regress/unittests/hostkeys/test_iterate.c index 7efb8e1..a330adc 100644 --- a/regress/unittests/hostkeys/test_iterate.c +++ b/regress/unittests/hostkeys/test_iterate.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_iterate.c,v 1.9 2024/01/11 01:45:58 djm Exp $ */ +/* $OpenBSD: test_iterate.c,v 1.11 2025/11/17 09:59:13 dtucker Exp $ */ /* * Regress test for hostfile.h hostkeys_foreach() * @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include @@ -94,15 +92,8 @@ check(struct hostkey_foreach_line *l, void *_ctx) expected->no_parse_keytype == KEY_ECDSA) skip = 1; #endif /* OPENSSL_HAS_ECC */ -#ifndef WITH_DSA - if (expected->l.keytype == KEY_DSA || - expected->no_parse_keytype == KEY_DSA) - skip = 1; -#endif #ifndef WITH_OPENSSL - if (expected->l.keytype == KEY_DSA || - expected->no_parse_keytype == KEY_DSA || - expected->l.keytype == KEY_RSA || + if (expected->l.keytype == KEY_RSA || expected->no_parse_keytype == KEY_RSA || expected->l.keytype == KEY_ECDSA || expected->no_parse_keytype == KEY_ECDSA) @@ -142,7 +133,7 @@ check(struct hostkey_foreach_line *l, void *_ctx) ASSERT_INT_EQ(sshkey_equal(l->key, expected->l.key), 1); } } - if (parse_key && !(l->comment == NULL && expected->l.comment == NULL)) + if (parse_key && l->comment != NULL && expected->l.comment != NULL) ASSERT_STRING_EQ(l->comment, expected->l.comment); return 0; } @@ -160,14 +151,9 @@ prepare_expected(struct expected *expected, size_t n) if (expected[i].l.keytype == KEY_ECDSA) continue; #endif /* OPENSSL_HAS_ECC */ -#ifndef WITH_DSA - if (expected[i].l.keytype == KEY_DSA) - continue; -#endif #ifndef WITH_OPENSSL switch (expected[i].l.keytype) { case KEY_RSA: - case KEY_DSA: case KEY_ECDSA: continue; } @@ -204,23 +190,9 @@ struct expected expected_full[] = { NULL, /* comment */ 0, /* note */ } }, - { "dsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { - NULL, - 2, - HKF_STATUS_OK, - 0, - NULL, - MRK_NONE, - "sisyphus.example.com", - NULL, - KEY_DSA, - NULL, /* filled at runtime */ - "DSA #1", - 0, - } }, { "ecdsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, - 3, + 2, HKF_STATUS_OK, 0, NULL, @@ -234,7 +206,7 @@ struct expected expected_full[] = { } }, { "ed25519_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, - 4, + 3, HKF_STATUS_OK, 0, NULL, @@ -248,7 +220,7 @@ struct expected expected_full[] = { } }, { "rsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, - 5, + 4, HKF_STATUS_OK, 0, NULL, @@ -262,7 +234,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, - 6, + 5, HKF_STATUS_COMMENT, 0, "", @@ -276,7 +248,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, - 7, + 6, HKF_STATUS_COMMENT, 0, "# Plain host keys, hostnames + addresses", @@ -288,23 +260,9 @@ struct expected expected_full[] = { NULL, 0, } }, - { "dsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { - NULL, - 8, - HKF_STATUS_OK, - 0, - NULL, - MRK_NONE, - "prometheus.example.com,192.0.2.1,2001:db8::1", - NULL, - KEY_DSA, - NULL, /* filled at runtime */ - "DSA #2", - 0, - } }, { "ecdsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, - 9, + 7, HKF_STATUS_OK, 0, NULL, @@ -318,7 +276,7 @@ struct expected expected_full[] = { } }, { "ed25519_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, - 10, + 8, HKF_STATUS_OK, 0, NULL, @@ -332,7 +290,7 @@ struct expected expected_full[] = { } }, { "rsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, - 11, + 9, HKF_STATUS_OK, 0, NULL, @@ -346,7 +304,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, - 12, + 10, HKF_STATUS_COMMENT, 0, "", @@ -360,7 +318,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, - 13, + 11, HKF_STATUS_COMMENT, 0, "# Some hosts with wildcard names / IPs", @@ -372,23 +330,9 @@ struct expected expected_full[] = { NULL, 0, } }, - { "dsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { - NULL, - 14, - HKF_STATUS_OK, - 0, - NULL, - MRK_NONE, - "*.example.com,192.0.2.*,2001:*", - NULL, - KEY_DSA, - NULL, /* filled at runtime */ - "DSA #3", - 0, - } }, { "ecdsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, - 15, + 12, HKF_STATUS_OK, 0, NULL, @@ -402,7 +346,7 @@ struct expected expected_full[] = { } }, { "ed25519_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, - 16, + 13, HKF_STATUS_OK, 0, NULL, @@ -416,7 +360,7 @@ struct expected expected_full[] = { } }, { "rsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, - 17, + 14, HKF_STATUS_OK, 0, NULL, @@ -430,7 +374,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, - 18, + 15, HKF_STATUS_COMMENT, 0, "", @@ -444,7 +388,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, - 19, + 16, HKF_STATUS_COMMENT, 0, "# Hashed hostname and address entries", @@ -456,23 +400,9 @@ struct expected expected_full[] = { NULL, 0, } }, - { "dsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { - NULL, - 20, - HKF_STATUS_OK, - 0, - NULL, - MRK_NONE, - NULL, - NULL, - KEY_DSA, - NULL, /* filled at runtime */ - "DSA #5", - 0, - } }, { "ecdsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { NULL, - 21, + 17, HKF_STATUS_OK, 0, NULL, @@ -486,7 +416,7 @@ struct expected expected_full[] = { } }, { "ed25519_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { NULL, - 22, + 18, HKF_STATUS_OK, 0, NULL, @@ -500,7 +430,7 @@ struct expected expected_full[] = { } }, { "rsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { NULL, - 23, + 19, HKF_STATUS_OK, 0, NULL, @@ -514,7 +444,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, - 24, + 20, HKF_STATUS_COMMENT, 0, "", @@ -531,51 +461,9 @@ struct expected expected_full[] = { * hostname and addresses in the pre-hashed known_hosts are split * to separate lines. */ - { "dsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { - NULL, - 25, - HKF_STATUS_OK, - 0, - NULL, - MRK_NONE, - NULL, - NULL, - KEY_DSA, - NULL, /* filled at runtime */ - "DSA #6", - 0, - } }, - { "dsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { - NULL, - 26, - HKF_STATUS_OK, - 0, - NULL, - MRK_NONE, - NULL, - NULL, - KEY_DSA, - NULL, /* filled at runtime */ - "DSA #6", - 0, - } }, - { "dsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { - NULL, - 27, - HKF_STATUS_OK, - 0, - NULL, - MRK_NONE, - NULL, - NULL, - KEY_DSA, - NULL, /* filled at runtime */ - "DSA #6", - 0, - } }, { "ecdsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { NULL, - 28, + 21, HKF_STATUS_OK, 0, NULL, @@ -589,7 +477,7 @@ struct expected expected_full[] = { } }, { "ecdsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { NULL, - 29, + 22, HKF_STATUS_OK, 0, NULL, @@ -603,7 +491,7 @@ struct expected expected_full[] = { } }, { "ecdsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { NULL, - 30, + 23, HKF_STATUS_OK, 0, NULL, @@ -617,7 +505,7 @@ struct expected expected_full[] = { } }, { "ed25519_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { NULL, - 31, + 24, HKF_STATUS_OK, 0, NULL, @@ -631,7 +519,7 @@ struct expected expected_full[] = { } }, { "ed25519_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { NULL, - 32, + 25, HKF_STATUS_OK, 0, NULL, @@ -645,7 +533,7 @@ struct expected expected_full[] = { } }, { "ed25519_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { NULL, - 33, + 26, HKF_STATUS_OK, 0, NULL, @@ -659,7 +547,7 @@ struct expected expected_full[] = { } }, { "rsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { NULL, - 34, + 27, HKF_STATUS_OK, 0, NULL, @@ -673,7 +561,7 @@ struct expected expected_full[] = { } }, { "rsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { NULL, - 35, + 28, HKF_STATUS_OK, 0, NULL, @@ -687,7 +575,7 @@ struct expected expected_full[] = { } }, { "rsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { NULL, - 36, + 29, HKF_STATUS_OK, 0, NULL, @@ -701,7 +589,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, - 37, + 30, HKF_STATUS_COMMENT, 0, "", @@ -715,7 +603,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, - 38, + 31, HKF_STATUS_COMMENT, 0, "", @@ -729,7 +617,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, - 39, + 32, HKF_STATUS_COMMENT, 0, "# Revoked and CA keys", @@ -743,7 +631,7 @@ struct expected expected_full[] = { } }, { "ed25519_4.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, - 40, + 33, HKF_STATUS_OK, 0, NULL, @@ -757,7 +645,7 @@ struct expected expected_full[] = { } }, { "ecdsa_4.pub" , -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, { NULL, - 41, + 34, HKF_STATUS_OK, 0, NULL, @@ -769,23 +657,9 @@ struct expected expected_full[] = { "ECDSA #4", 0, } }, - { "dsa_4.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, 0, 0, -1, { - NULL, - 42, - HKF_STATUS_OK, - 0, - NULL, - MRK_CA, - "*.example.com", - NULL, - KEY_DSA, - NULL, /* filled at runtime */ - "DSA #4", - 0, - } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, - 43, + 35, HKF_STATUS_COMMENT, 0, "", @@ -799,7 +673,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, - 44, + 36, HKF_STATUS_COMMENT, 0, "# Some invalid lines", @@ -813,7 +687,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, - 45, + 37, HKF_STATUS_INVALID, 0, NULL, @@ -827,7 +701,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, - 46, + 38, HKF_STATUS_INVALID, 0, NULL, @@ -841,7 +715,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, { NULL, - 47, + 39, HKF_STATUS_INVALID, 0, NULL, @@ -853,9 +727,9 @@ struct expected expected_full[] = { NULL, 0, } }, - { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { + { NULL, HKF_STATUS_OK, KEY_ED25519, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, - 48, + 40, HKF_STATUS_INVALID, /* Would be ok if key not parsed */ 0, NULL, @@ -869,7 +743,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, - 49, + 41, HKF_STATUS_INVALID, 0, NULL, @@ -883,7 +757,7 @@ struct expected expected_full[] = { } }, { NULL, HKF_STATUS_OK, KEY_RSA, HKF_MATCH_HOST, 0, 0, 0, -1, { NULL, - 50, + 42, HKF_STATUS_INVALID, /* Would be ok if key not parsed */ 0, NULL, diff --git a/regress/unittests/hostkeys/testdata/dsa_1.pub b/regress/unittests/hostkeys/testdata/dsa_1.pub deleted file mode 100644 index 56e1e37..0000000 --- a/regress/unittests/hostkeys/testdata/dsa_1.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-dss AAAAB3NzaC1kc3MAAACBAOqffHxEW4c+Z9q/r3l4sYK8F7qrBsU8XF9upGsW62T9InROFFq9IO0x3pQ6mDA0Wtw0sqcDmkPCHPyP4Ok/fU3/drLaZusHoVYu8pBBrWsIDrKgkeX9TEodBsSrYdl4Sqtqq9EZv9+DttV6LStZrgYyUTOKwOF95wGantpLynX5AAAAFQDdt+zjRNlETDsgmxcSYFgREirJrQAAAIBQlrPaiPhR24FhnMLcHH4016vL7AqDDID6Qw7PhbXGa4/XlxWMIigjBKrIPKvnZ6p712LSnCKtcbfdx0MtmJlNa01CYqPaRhgRaf+uGdvTkTUcdaq8R5lLJL+JMNwUhcC8ijm3NqEjXjffuebGe1EzIeiITbA7Nndcd+GytwRDegAAAIEAkRYPjSVcUxfUHhHdpP6V8CuY1+CYSs9EPJ7iiWTDuXWVIBTU32oJLAnrmAcOwtIzEfPvm+rff5FI/Yhon2pB3VTXhPPEBjYzE5qANanAT4e6tzAVc5f3DUhHaDknwRYfDz86GFvuLtDjeE/UZ9t6OofYoEsCBpYozLAprBvNIQY= DSA #1 diff --git a/regress/unittests/hostkeys/testdata/dsa_2.pub b/regress/unittests/hostkeys/testdata/dsa_2.pub deleted file mode 100644 index 394e0bf..0000000 --- a/regress/unittests/hostkeys/testdata/dsa_2.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-dss AAAAB3NzaC1kc3MAAACBAI38Hy/61/O5Bp6yUG8J5XQCeNjRS0xvjlCdzKLyXCueMa+L+X2L/u9PWUsy5SVbTjGgpB8sF6UkCNsV+va7S8zCCHas2MZ7GPlxP6GZBkRPTIFR0N/Pu7wfBzDQz0t0iL4VmxBfTBQv/SxkGWZg+yHihIQP9fwdSAwD/7aVh6ItAAAAFQDSyihIUlINlswM0PJ8wXSti3yIMwAAAIB+oqzaB6ozqs8YxpN5oQOBa/9HEBQEsp8RSIlQmVubXRNgktp42n+Ii1waU9UUk8DX5ahhIeR6B7ojWkqmDAji4SKpoHf4kmr6HvYo85ZSTSx0W4YK/gJHSpDJwhlT52tAfb1JCbWSObjl09B4STv7KedCHcR5oXQvvrV+XoKOSAAAAIAue/EXrs2INw1RfaKNHC0oqOMxmRitv0BFMuNVPo1VDj39CE5kA7AHjwvS1TNeaHtK5Hhgeb6vsmLmNPTOc8xCob0ilyQbt9O0GbONeF2Ge7D2UJyULA/hxql+tCYFIC6yUrmo35fF9XiNisXLoaflk9fjp7ROWWVwnki/jstaQw== DSA #2 diff --git a/regress/unittests/hostkeys/testdata/dsa_3.pub b/regress/unittests/hostkeys/testdata/dsa_3.pub deleted file mode 100644 index e506ea4..0000000 --- a/regress/unittests/hostkeys/testdata/dsa_3.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-dss AAAAB3NzaC1kc3MAAACBAI6lz2Ip9bzE7TGuDD4SjO9S4Ac90gq0h6ai1O06eI8t/Ot2uJ5Jk2QyVr2jvIZHDl/5bwBx7+5oyjlwRoUrAPPD814wf5tU2tSnmdu1Wbf0cBswif5q0r4tevzmopp/AtgH11QHo3u0/pfyJd10qBDLV2FaYSKMmZvyPfZJ0s9pAAAAFQD5Eqjl6Rx2qVePodD9OwAPT0bU6wAAAIAfnDm6csZF0sFaJR3NIJvaYgSGr8s7cqlsk2gLltB/1wOOO2yX+NeEC+B0H93hlMfaUsPa08bwgmYxnavSMqEBpmtPceefJiEd68zwYqXd38f88wyWZ9Z5iwaI/6OVZPHzCbDxOa4ewVTevRNYUKP1xUTZNT8/gSMfZLYPk4T2AQAAAIAUKroozRMyV+3V/rxt0gFnNxRXBKk+9cl3vgsQ7ktkI9cYg7V1T2K0XF21AVMK9gODszy6PBJjV6ruXBV6TRiqIbQauivp3bHHKYsG6wiJNqwdbVwIjfvv8nn1qFoZQLXG3sdONr9NwN8KzrX89OV0BlR2dVM5qqp+YxOXymP9yg== DSA #3 diff --git a/regress/unittests/hostkeys/testdata/dsa_4.pub b/regress/unittests/hostkeys/testdata/dsa_4.pub deleted file mode 100644 index 8552c38..0000000 --- a/regress/unittests/hostkeys/testdata/dsa_4.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-dss AAAAB3NzaC1kc3MAAACBAKvjnFHm0VvMr5h2Zu3nURsxQKGoxm+DCzYDxRYcilK07Cm5c4XTrFbA2X86+9sGs++W7QRMcTJUYIg0a+UtIMtAjwORd6ZPXM2K5dBW+gh1oHyvKi767tWX7I2c+1ZPJDY95mUUfZQUEfdy9eGDSBmw/pSsveQ1ur6XNUh/MtP/AAAAFQDHnXk/9jBJAdce1pHtLWnbdPSGdQAAAIEAm2OLy8tZBfiEO3c3X1yyB/GTcDwrQCqRMDkhnsmrliec3dWkOfNTzu+MrdvF8ymTWLEqPpbMheYtvNyZ3TF0HO5W7aVBpdGZbOdOAIfB+6skqGbI8A5Up1d7dak/bSsqL2r5NjwbDOdq+1hBzzvbl/qjh+sQarV2zHrpKoQaV28AAACANtkBVedBbqIAdphCrN/LbUi9WlyuF9UZz+tlpVLYrj8GJVwnplV2tvOmUw6yP5/pzCimTsao8dpL5PWxm7fKxLWVxA+lEsA4WeC885CiZn8xhdaJOCN+NyJ2bqkz+4VPI7oDGBm0aFwUqJn+M1PiSgvI50XdF2dBsFRTRNY0wzA= DSA #4 diff --git a/regress/unittests/hostkeys/testdata/dsa_5.pub b/regress/unittests/hostkeys/testdata/dsa_5.pub deleted file mode 100644 index 149e1ef..0000000 --- a/regress/unittests/hostkeys/testdata/dsa_5.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-dss AAAAB3NzaC1kc3MAAACBALrFy7w5ihlaOG+qR+6fj+vm5EQaO3qwxgACLcgH+VfShuOG4mkx8qFJmf+OZ3fh5iKngjNZfKtfcqI7zHWdk6378TQfQC52/kbZukjNXOLCpyNkogahcjA00onIoTK1RUDuMW28edAHwPFbpttXDTaqis+8JPMY8hZwsZGENCzTAAAAFQD6+It5vozwGgaN9ROYPMlByhi6jwAAAIBz2mcAC694vNzz9b6614gkX9d9E99PzJYfU1MPkXDziKg7MrjBw7Opd5y1jL09S3iL6lSTlHkKwVKvQ3pOwWRwXXRrKVus4I0STveoApm526jmp6mY0YEtqR98vMJ0v97h1ydt8FikKlihefCsnXVicb8887PXs2Y8C6GuFT3tfQAAAIBbmHtV5tPcrMRDkULhaQ/Whap2VKvT2DUhIHA7lx6oy/KpkltOpxDZOIGUHKqffGbiR7Jh01/y090AY5L2eCf0S2Ytx93+eADwVVpJbFJo6zSwfeey2Gm6L2oA+rCz9zTdmtZoekpD3/RAOQjnJIAPwbs7mXwabZTw4xRtiYIRrw== DSA #5 diff --git a/regress/unittests/hostkeys/testdata/dsa_6.pub b/regress/unittests/hostkeys/testdata/dsa_6.pub deleted file mode 100644 index edbb976..0000000 --- a/regress/unittests/hostkeys/testdata/dsa_6.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6 diff --git a/regress/unittests/hostkeys/testdata/known_hosts b/regress/unittests/hostkeys/testdata/known_hosts index 4446f45..5298e3e 100644 --- a/regress/unittests/hostkeys/testdata/known_hosts +++ b/regress/unittests/hostkeys/testdata/known_hosts @@ -1,30 +1,23 @@ # Plain host keys, plain host names -sisyphus.example.com ssh-dss AAAAB3NzaC1kc3MAAACBAOqffHxEW4c+Z9q/r3l4sYK8F7qrBsU8XF9upGsW62T9InROFFq9IO0x3pQ6mDA0Wtw0sqcDmkPCHPyP4Ok/fU3/drLaZusHoVYu8pBBrWsIDrKgkeX9TEodBsSrYdl4Sqtqq9EZv9+DttV6LStZrgYyUTOKwOF95wGantpLynX5AAAAFQDdt+zjRNlETDsgmxcSYFgREirJrQAAAIBQlrPaiPhR24FhnMLcHH4016vL7AqDDID6Qw7PhbXGa4/XlxWMIigjBKrIPKvnZ6p712LSnCKtcbfdx0MtmJlNa01CYqPaRhgRaf+uGdvTkTUcdaq8R5lLJL+JMNwUhcC8ijm3NqEjXjffuebGe1EzIeiITbA7Nndcd+GytwRDegAAAIEAkRYPjSVcUxfUHhHdpP6V8CuY1+CYSs9EPJ7iiWTDuXWVIBTU32oJLAnrmAcOwtIzEfPvm+rff5FI/Yhon2pB3VTXhPPEBjYzE5qANanAT4e6tzAVc5f3DUhHaDknwRYfDz86GFvuLtDjeE/UZ9t6OofYoEsCBpYozLAprBvNIQY= DSA #1 sisyphus.example.com ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF6yQEtD9yBw9gmDRf477WBBzvWhAa0ioBI3nbA4emKykj0RbuQd5C4XdQAEOZGzE7v//FcCjwB2wi+JH5eKkxCtN6CjohDASZ1huoIV2UVyYIicZJEEOg1IWjjphvaxtw== ECDSA #1 sisyphus.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK9ks7jkua5YWIwByRnnnc6UPJQWI75O0e/UJdPYU1JI ED25519 #1 sisyphus.example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDg4hB4vAZHJ0PVRiJajOv/GlytFWNpv5/9xgB9+5BIbvp8LOrFZ5D9K0Gsmwpd4G4rfaAz8j896DhMArg0vtkilIPPGt/6VzWMERgvaIQPJ/IE99X3+fjcAG56oAWwy29JX10lQMzBPU6XJIaN/zqpkb6qUBiAHBdLpxrFBBU0/w== RSA #1 # Plain host keys, hostnames + addresses -prometheus.example.com,192.0.2.1,2001:db8::1 ssh-dss AAAAB3NzaC1kc3MAAACBAI38Hy/61/O5Bp6yUG8J5XQCeNjRS0xvjlCdzKLyXCueMa+L+X2L/u9PWUsy5SVbTjGgpB8sF6UkCNsV+va7S8zCCHas2MZ7GPlxP6GZBkRPTIFR0N/Pu7wfBzDQz0t0iL4VmxBfTBQv/SxkGWZg+yHihIQP9fwdSAwD/7aVh6ItAAAAFQDSyihIUlINlswM0PJ8wXSti3yIMwAAAIB+oqzaB6ozqs8YxpN5oQOBa/9HEBQEsp8RSIlQmVubXRNgktp42n+Ii1waU9UUk8DX5ahhIeR6B7ojWkqmDAji4SKpoHf4kmr6HvYo85ZSTSx0W4YK/gJHSpDJwhlT52tAfb1JCbWSObjl09B4STv7KedCHcR5oXQvvrV+XoKOSAAAAIAue/EXrs2INw1RfaKNHC0oqOMxmRitv0BFMuNVPo1VDj39CE5kA7AHjwvS1TNeaHtK5Hhgeb6vsmLmNPTOc8xCob0ilyQbt9O0GbONeF2Ge7D2UJyULA/hxql+tCYFIC6yUrmo35fF9XiNisXLoaflk9fjp7ROWWVwnki/jstaQw== DSA #2 prometheus.example.com,192.0.2.1,2001:db8::1 ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAB8qVcXwgBM92NCmReQlPrZAoui4Bz/mW0VUBFOpHXXW1n+15b/Y7Pc6UBd/ITTZmaBciXY+PWaSBGdwc5GdqGdLgFyJ/QAGrFMPNpVutm/82gNQzlxpNwjbMcKyiZEXzSgnjS6DzMQ0WuSMdzIBXq8OW/Kafxg4ZkU6YqALUXxlQMZuQ== ECDSA #2 prometheus.example.com,192.0.2.1,2001:db8::1 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIBp6PVW0z2o9C4Ukv/JOgmK7QMFe1pD1s3ADFF7IQob ED25519 #2 prometheus.example.com,192.0.2.1,2001:db8::1 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDmbUhNabB5AmBDX6GNHZ3lbn7pRxqfpW+f53QqNGlK0sLV+0gkMIrOfUp1kdE2ZLE6tfzdicatj/RlH6/wuo4yyYb+Pyx3G0vxdmAIiA4aANq38XweDucBC0TZkRWVHK+Gs5V/uV0z7N0axJvkkJujMLvST3CRiiWwlficBc6yVQ== RSA #2 # Some hosts with wildcard names / IPs -*.example.com,192.0.2.*,2001:* ssh-dss AAAAB3NzaC1kc3MAAACBAI6lz2Ip9bzE7TGuDD4SjO9S4Ac90gq0h6ai1O06eI8t/Ot2uJ5Jk2QyVr2jvIZHDl/5bwBx7+5oyjlwRoUrAPPD814wf5tU2tSnmdu1Wbf0cBswif5q0r4tevzmopp/AtgH11QHo3u0/pfyJd10qBDLV2FaYSKMmZvyPfZJ0s9pAAAAFQD5Eqjl6Rx2qVePodD9OwAPT0bU6wAAAIAfnDm6csZF0sFaJR3NIJvaYgSGr8s7cqlsk2gLltB/1wOOO2yX+NeEC+B0H93hlMfaUsPa08bwgmYxnavSMqEBpmtPceefJiEd68zwYqXd38f88wyWZ9Z5iwaI/6OVZPHzCbDxOa4ewVTevRNYUKP1xUTZNT8/gSMfZLYPk4T2AQAAAIAUKroozRMyV+3V/rxt0gFnNxRXBKk+9cl3vgsQ7ktkI9cYg7V1T2K0XF21AVMK9gODszy6PBJjV6ruXBV6TRiqIbQauivp3bHHKYsG6wiJNqwdbVwIjfvv8nn1qFoZQLXG3sdONr9NwN8KzrX89OV0BlR2dVM5qqp+YxOXymP9yg== DSA #3 *.example.com,192.0.2.*,2001:* ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIb3BhJZk+vUQPg5TQc1koIzuGqloCq7wjr9LjlhG24IBeiFHLsdWw74HDlH4DrOmlxToVYk2lTdnjARleRByjk= ECDSA #3 *.example.com,192.0.2.*,2001:* ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBlYfExtYZAPqYvYdrlpGlSWhh/XNHcH3v3c2JzsVNbB ED25519 #3 *.example.com,192.0.2.*,2001:* ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDX8F93W3SH4ZSus4XUQ2cw9dqcuyUETTlKEeGv3zlknV3YCoe2Mp04naDhiuwj8sOsytrZSESzLY1ZEyzrjxE6ZFVv8NKgck/AbRjcwlRFOcx9oKUxOrXRa0IoXlTq0kyjKCJfaHBKnGitZThknCPTbVmpATkm5xx6J0WEDozfoQ== RSA #3 # Hashed hostname and address entries -|1|z3xOIdT5ue3Vuf3MzT67kaioqjw=|GZhhe5uwDOBQrC9N4cCjpbLpSn4= ssh-dss AAAAB3NzaC1kc3MAAACBALrFy7w5ihlaOG+qR+6fj+vm5EQaO3qwxgACLcgH+VfShuOG4mkx8qFJmf+OZ3fh5iKngjNZfKtfcqI7zHWdk6378TQfQC52/kbZukjNXOLCpyNkogahcjA00onIoTK1RUDuMW28edAHwPFbpttXDTaqis+8JPMY8hZwsZGENCzTAAAAFQD6+It5vozwGgaN9ROYPMlByhi6jwAAAIBz2mcAC694vNzz9b6614gkX9d9E99PzJYfU1MPkXDziKg7MrjBw7Opd5y1jL09S3iL6lSTlHkKwVKvQ3pOwWRwXXRrKVus4I0STveoApm526jmp6mY0YEtqR98vMJ0v97h1ydt8FikKlihefCsnXVicb8887PXs2Y8C6GuFT3tfQAAAIBbmHtV5tPcrMRDkULhaQ/Whap2VKvT2DUhIHA7lx6oy/KpkltOpxDZOIGUHKqffGbiR7Jh01/y090AY5L2eCf0S2Ytx93+eADwVVpJbFJo6zSwfeey2Gm6L2oA+rCz9zTdmtZoekpD3/RAOQjnJIAPwbs7mXwabZTw4xRtiYIRrw== DSA #5 |1|B7t/AYabn8zgwU47Cb4A/Nqt3eI=|arQPZyRphkzisr7w6wwikvhaOyE= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIudcagzq4QPtP1jkpje34+0POLB0jwT64hqrbCqhTH2T800KDZ0h2vwlJYa3OP3Oqru9AB5pnuHsKw7mAhUGY= ECDSA #5 |1|JR81WxEocTP5d7goIRkl8fHBbno=|l6sj6FOsoXxgEZMzn/BnOfPKN68= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINf63qSV8rD57N+digID8t28WVhd3Yf2K2UhaoG8TsWQ ED25519 #5 |1|W7x4zY6KtTZJgsopyOusJqvVPag=|QauLt7hKezBZFZi2i4Xopho7Nsk= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC/C15Q4sfnk7BZff1er8bscay+5s51oD4eWArlHWMK/ZfYeeTAccTy+7B7Jv+MS4nKCpflrvJI2RQz4kS8vF0ATdBbi4jeWefStlHNg0HLhnCY7NAfDIlRdaN9lm3Pqm2vmr+CkqwcJaSpycDg8nPN9yNAuD6pv7NDuUnECezojQ== RSA #5 -|1|mxnU8luzqWLvfVi5qBm5xVIyCRM=|9Epopft7LBd80Bf6RmWPIpwa8yU= ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6 -|1|klvLmvh2vCpkNMDEjVvrE8SJWTg=|e/dqEEBLnbgqmwEesl4cDRu/7TM= ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6 -|1|wsk3ddB3UjuxEsoeNCeZjZ6NvZs=|O3O/q2Z/u7DrxoTiIq6kzCevQT0= ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6 |1|B8epmkLSni+vGZDijr/EwxeR2k4=|7ct8yzNOVJhKm3ZD2w0XIT7df8E= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6 |1|JojD885UhYhbCu571rgyM/5PpYU=|BJaU2aE1FebQZy3B5tzTDRWFRG0= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6 |1|5t7UDHDybVrDZVQPCpwdnr6nk4k=|EqJ73W/veIL3H2x+YWHcJxI5ETA= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6 @@ -39,12 +32,11 @@ prometheus.example.com,192.0.2.1,2001:db8::1 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAA # Revoked and CA keys @revoked sisyphus.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDFP8L9REfN/iYy1KIRtFqSCn3V2+vOCpoZYENFGLdOF ED25519 #4 @cert-authority prometheus.example.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHZd0OXHIWwK3xnjAdMZ1tojxWycdu38pORO/UX5cqsKMgGCKQVBWWO3TFk1ePkGIE9VMWT1hCGqWRRwYlH+dSE= ECDSA #4 -@cert-authority *.example.com ssh-dss AAAAB3NzaC1kc3MAAACBAKvjnFHm0VvMr5h2Zu3nURsxQKGoxm+DCzYDxRYcilK07Cm5c4XTrFbA2X86+9sGs++W7QRMcTJUYIg0a+UtIMtAjwORd6ZPXM2K5dBW+gh1oHyvKi767tWX7I2c+1ZPJDY95mUUfZQUEfdy9eGDSBmw/pSsveQ1ur6XNUh/MtP/AAAAFQDHnXk/9jBJAdce1pHtLWnbdPSGdQAAAIEAm2OLy8tZBfiEO3c3X1yyB/GTcDwrQCqRMDkhnsmrliec3dWkOfNTzu+MrdvF8ymTWLEqPpbMheYtvNyZ3TF0HO5W7aVBpdGZbOdOAIfB+6skqGbI8A5Up1d7dak/bSsqL2r5NjwbDOdq+1hBzzvbl/qjh+sQarV2zHrpKoQaV28AAACANtkBVedBbqIAdphCrN/LbUi9WlyuF9UZz+tlpVLYrj8GJVwnplV2tvOmUw6yP5/pzCimTsao8dpL5PWxm7fKxLWVxA+lEsA4WeC885CiZn8xhdaJOCN+NyJ2bqkz+4VPI7oDGBm0aFwUqJn+M1PiSgvI50XdF2dBsFRTRNY0wzA= DSA #4 # Some invalid lines -@what sisyphus.example.com ssh-dss AAAAB3NzaC1kc3MAAACBAOqffHxEW4c+Z9q/r3l4sYK8F7qrBsU8XF9upGsW62T9InROFFq9IO0x3pQ6mDA0Wtw0sqcDmkPCHPyP4Ok/fU3/drLaZusHoVYu8pBBrWsIDrKgkeX9TEodBsSrYdl4Sqtqq9EZv9+DttV6LStZrgYyUTOKwOF95wGantpLynX5AAAAFQDdt+zjRNlETDsgmxcSYFgREirJrQAAAIBQlrPaiPhR24FhnMLcHH4016vL7AqDDID6Qw7PhbXGa4/XlxWMIigjBKrIPKvnZ6p712LSnCKtcbfdx0MtmJlNa01CYqPaRhgRaf+uGdvTkTUcdaq8R5lLJL+JMNwUhcC8ijm3NqEjXjffuebGe1EzIeiITbA7Nndcd+GytwRDegAAAIEAkRYPjSVcUxfUHhHdpP6V8CuY1+CYSs9EPJ7iiWTDuXWVIBTU32oJLAnrmAcOwtIzEfPvm+rff5FI/Yhon2pB3VTXhPPEBjYzE5qANanAT4e6tzAVc5f3DUhHaDknwRYfDz86GFvuLtDjeE/UZ9t6OofYoEsCBpYozLAprBvNIQY= DSA #1 +@what ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDg4hB4vAZHJ0PVRiJajOv/GlytFWNpv5/9xgB9+5BIbvp8LOrFZ5D9K0Gsmwpd4G4rfaAz8j896DhMArg0vtkilIPPGt/6VzWMERgvaIQPJ/IE99X3+fjcAG56oAWwy29JX10lQMzBPU6XJIaN/zqpkb6qUBiAHBdLpxrFBBU0/w== RSA #1 sisyphus.example.com prometheus.example.com ssh-ed25519 -sisyphus.example.com ssh-dsa AAAATgAAAAdz +sisyphus.example.com ssh-ed25519 AAAATgAAAAdz sisyphus.example.com ssh-XXX AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg== prometheus.example.com ssh-rsa AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg== diff --git a/regress/unittests/hostkeys/tests.c b/regress/unittests/hostkeys/tests.c index 92c7646..c6e17fa 100644 --- a/regress/unittests/hostkeys/tests.c +++ b/regress/unittests/hostkeys/tests.c @@ -1,10 +1,16 @@ -/* $OpenBSD: tests.c,v 1.1 2015/02/16 22:18:34 djm Exp $ */ +/* $OpenBSD: tests.c,v 1.2 2025/04/15 04:00:42 djm Exp $ */ /* * Regress test for known_hosts-related API. * * Placed in the public domain */ +#include "includes.h" + +#include + +#include "../test_helper/test_helper.h" + void tests(void); void test_iterate(void); /* test_iterate.c */ @@ -14,3 +20,8 @@ tests(void) test_iterate(); } +void +benchmarks(void) +{ + printf("no benchmarks\n"); +} diff --git a/regress/unittests/kex/Makefile b/regress/unittests/kex/Makefile index ca4f0ee..7a53978 100644 --- a/regress/unittests/kex/Makefile +++ b/regress/unittests/kex/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.16 2024/09/09 03:13:39 djm Exp $ +# $OpenBSD: Makefile,v 1.21 2026/02/06 23:39:14 dtucker Exp $ PROG=test_kex SRCS=tests.c test_kex.c test_proposal.c @@ -6,12 +6,12 @@ SRCS=tests.c test_kex.c test_proposal.c # From usr.bin/ssh SRCS+=sshbuf-getput-basic.c sshbuf-getput-crypto.c sshbuf-misc.c sshbuf.c SRCS+=sshbuf-io.c atomicio.c sshkey.c authfile.c cipher.c log.c ssh-rsa.c -SRCS+=ssh-dss.c ssh-ecdsa.c ssh-ed25519.c mac.c umac.c umac128.c hmac.c misc.c +SRCS+=ssh-ecdsa.c ssh-ed25519.c mac.c umac.c umac128.c hmac.c misc.c SRCS+=ssherr.c uidswap.c cleanup.c xmalloc.c match.c krl.c fatal.c SRCS+=addr.c addrmatch.c bitmap.c packet.c dispatch.c canohost.c ssh_api.c -SRCS+=compat.c ed25519.c hash.c +SRCS+=compat.c SRCS+=cipher-chachapoly.c chacha.c poly1305.c ssh-ecdsa-sk.c ssh-sk.c -SRCS+=ssh-ed25519-sk.c sk-usbhid.c +SRCS+=ssh-ed25519-sk.c sk-usbhid.c ssh-pkcs11-client.c ssherr-libcrypto.c SRCS+= kex.c SRCS+= kex-names.c @@ -29,13 +29,13 @@ SRCS+= kexmlkem768x25519.c SRCS+= sntrup761.c SRCS+= utf8.c -SRCS+=digest-openssl.c -#SRCS+=digest-libc.c +SRCS+=digest-openssl.c ed25519-openssl.c +#SRCS+=digest-libc.c ed25519.c REGRESS_TARGETS=run-regress-${PROG} run-regress-${PROG}: ${PROG} - env ${TEST_ENV} ./${PROG} + env ${TEST_ENV} ./${PROG} ${UNITTEST_ARGS} .include diff --git a/regress/unittests/kex/test_kex.c b/regress/unittests/kex/test_kex.c index caf8f57..16c2f2d 100644 --- a/regress/unittests/kex/test_kex.c +++ b/regress/unittests/kex/test_kex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_kex.c,v 1.9 2024/09/09 03:13:39 djm Exp $ */ +/* $OpenBSD: test_kex.c,v 1.12 2025/08/21 05:55:30 djm Exp $ */ /* * Regress test KEX * @@ -8,10 +8,9 @@ #include "includes.h" #include +#include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include @@ -76,7 +75,8 @@ run_kex(struct ssh *client, struct ssh *server) } static void -do_kex_with_key(char *kex, int keytype, int bits) +do_kex_with_key(char *kex, char *cipher, char *mac, + struct sshkey *key, int keytype, int bits) { struct ssh *client = NULL, *server = NULL, *server2 = NULL; struct sshkey *private, *public; @@ -85,9 +85,14 @@ do_kex_with_key(char *kex, int keytype, int bits) char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; char *keyname = NULL; - TEST_START("sshkey_generate"); - ASSERT_INT_EQ(sshkey_generate(keytype, bits, &private), 0); - TEST_DONE(); + if (key != NULL) { + private = key; + keytype = key->type; + } else { + TEST_START("sshkey_generate"); + ASSERT_INT_EQ(sshkey_generate(keytype, bits, &private), 0); + TEST_DONE(); + } TEST_START("sshkey_from_private"); ASSERT_INT_EQ(sshkey_from_private(private, &public), 0); @@ -97,6 +102,14 @@ do_kex_with_key(char *kex, int keytype, int bits) memcpy(kex_params.proposal, myproposal, sizeof(myproposal)); if (kex != NULL) kex_params.proposal[PROPOSAL_KEX_ALGS] = kex; + if (cipher != NULL) { + kex_params.proposal[PROPOSAL_ENC_ALGS_CTOS] = cipher; + kex_params.proposal[PROPOSAL_ENC_ALGS_STOC] = cipher; + } + if (mac != NULL) { + kex_params.proposal[PROPOSAL_MAC_ALGS_CTOS] = mac; + kex_params.proposal[PROPOSAL_MAC_ALGS_STOC] = mac; + } keyname = strdup(sshkey_ssh_name(private)); ASSERT_PTR_NE(keyname, NULL); kex_params.proposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = keyname; @@ -147,6 +160,9 @@ do_kex_with_key(char *kex, int keytype, int bits) server2->kex->kex[KEX_DH_GRP14_SHA1] = kex_gen_server; server2->kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; server2->kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; + server2->kex->kex[KEX_DH_GRP14_SHA256] = kex_gen_server; + server2->kex->kex[KEX_DH_GRP16_SHA512] = kex_gen_server; + server2->kex->kex[KEX_DH_GRP18_SHA512] = kex_gen_server; #ifdef OPENSSL_HAS_ECC server2->kex->kex[KEX_ECDH_SHA2] = kex_gen_server; #endif /* OPENSSL_HAS_ECC */ @@ -167,7 +183,8 @@ do_kex_with_key(char *kex, int keytype, int bits) TEST_DONE(); TEST_START("cleanup"); - sshkey_free(private); + if (key == NULL) + sshkey_free(private); sshkey_free(public); ssh_free(client); ssh_free(server); @@ -179,25 +196,40 @@ do_kex_with_key(char *kex, int keytype, int bits) static void do_kex(char *kex) { -#if 0 - log_init("test_kex", SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 1); -#endif + struct sshkey *key = NULL; + char name[256]; + + if (test_is_benchmark()) { + snprintf(name, sizeof(name), "generate %s", kex); + TEST_START(name); + ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 0, &key), 0); + TEST_DONE(); + snprintf(name, sizeof(name), "KEX %s", kex); + BENCH_START(name); + /* + * NB. use a cipher/MAC here that requires minimal bits from + * the KEX to avoid DH-GEX taking forever. + */ + do_kex_with_key(kex, "aes128-ctr", "hmac-sha2-256", key, + KEY_ED25519, 256); + BENCH_FINISH("kex"); + sshkey_free(key); + return; + } + #ifdef WITH_OPENSSL - do_kex_with_key(kex, KEY_RSA, 2048); -#ifdef WITH_DSA - do_kex_with_key(kex, KEY_DSA, 1024); -#endif -#ifdef OPENSSL_HAS_ECC - do_kex_with_key(kex, KEY_ECDSA, 256); -#endif /* OPENSSL_HAS_ECC */ + do_kex_with_key(kex, NULL, NULL, NULL, KEY_RSA, 2048); +# ifdef OPENSSL_HAS_ECC + do_kex_with_key(kex, NULL, NULL, NULL, KEY_ECDSA, 256); +# endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ - do_kex_with_key(kex, KEY_ED25519, 256); + do_kex_with_key(kex, NULL, NULL, NULL, KEY_ED25519, 256); } void kex_tests(void) { - do_kex("curve25519-sha256@libssh.org"); + do_kex("curve25519-sha256"); #ifdef WITH_OPENSSL #ifdef OPENSSL_HAS_ECC do_kex("ecdh-sha2-nistp256"); @@ -208,11 +240,16 @@ kex_tests(void) do_kex("diffie-hellman-group-exchange-sha1"); do_kex("diffie-hellman-group14-sha1"); do_kex("diffie-hellman-group1-sha1"); + if (test_is_benchmark()) { + do_kex("diffie-hellman-group14-sha256"); + do_kex("diffie-hellman-group16-sha512"); + do_kex("diffie-hellman-group18-sha512"); + } # ifdef USE_MLKEM768X25519 do_kex("mlkem768x25519-sha256"); # endif /* USE_MLKEM768X25519 */ # ifdef USE_SNTRUP761X25519 - do_kex("sntrup761x25519-sha512@openssh.com"); + do_kex("sntrup761x25519-sha512"); # endif /* USE_SNTRUP761X25519 */ #endif /* WITH_OPENSSL */ } diff --git a/regress/unittests/kex/test_proposal.c b/regress/unittests/kex/test_proposal.c index fa4192b..01bf7e5 100644 --- a/regress/unittests/kex/test_proposal.c +++ b/regress/unittests/kex/test_proposal.c @@ -10,9 +10,7 @@ #include #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include diff --git a/regress/unittests/kex/tests.c b/regress/unittests/kex/tests.c index d3044f0..d8a38e0 100644 --- a/regress/unittests/kex/tests.c +++ b/regress/unittests/kex/tests.c @@ -1,8 +1,12 @@ -/* $OpenBSD: tests.c,v 1.3 2023/03/06 12:15:47 dtucker Exp $ */ +/* $OpenBSD: tests.c,v 1.4 2025/04/15 04:00:42 djm Exp $ */ /* * Placed in the public domain */ +#include "includes.h" + +#include + #include "../test_helper/test_helper.h" void kex_tests(void); @@ -16,3 +20,10 @@ tests(void) kex_proposal_tests(); kex_proposal_populate_tests(); } + +void +benchmarks(void) +{ + printf("\n"); + kex_tests(); +} diff --git a/regress/unittests/match/Makefile b/regress/unittests/match/Makefile index 939163d..558e10b 100644 --- a/regress/unittests/match/Makefile +++ b/regress/unittests/match/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.5 2021/01/09 12:24:31 dtucker Exp $ +# $OpenBSD: Makefile,v 1.7 2026/02/06 23:39:14 dtucker Exp $ PROG=test_match SRCS=tests.c @@ -6,11 +6,11 @@ SRCS=tests.c # From usr.bin/ssh SRCS+=sshbuf-getput-basic.c sshbuf-getput-crypto.c sshbuf-misc.c sshbuf.c SRCS+=match.c misc.c log.c uidswap.c fatal.c ssherr.c addrmatch.c xmalloc.c -SRCS+=cleanup.c atomicio.c addr.c +SRCS+=cleanup.c atomicio.c addr.c ssherr-libcrypto.c REGRESS_TARGETS=run-regress-${PROG} run-regress-${PROG}: ${PROG} - env ${TEST_ENV} ./${PROG} + env ${TEST_ENV} ./${PROG} ${UNITTEST_ARGS} .include diff --git a/regress/unittests/match/tests.c b/regress/unittests/match/tests.c index f00d1f9..163a3a2 100644 --- a/regress/unittests/match/tests.c +++ b/regress/unittests/match/tests.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tests.c,v 1.8 2021/12/14 21:25:27 deraadt Exp $ */ +/* $OpenBSD: tests.c,v 1.9 2025/04/15 04:00:42 djm Exp $ */ /* * Regress test for matching functions * @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include @@ -129,3 +127,9 @@ tests(void) * int addr_match_cidr_list(const char *, const char *); */ } + +void +benchmarks(void) +{ + printf("no benchmarks\n"); +} diff --git a/regress/unittests/misc/Makefile b/regress/unittests/misc/Makefile index d2be393..c2d3924 100644 --- a/regress/unittests/misc/Makefile +++ b/regress/unittests/misc/Makefile @@ -1,7 +1,8 @@ -# $OpenBSD: Makefile,v 1.9 2023/01/06 02:59:50 djm Exp $ +# $OpenBSD: Makefile,v 1.13 2026/02/06 23:39:14 dtucker Exp $ PROG=test_misc SRCS=tests.c +SRCS+= test_misc.c SRCS+= test_convtime.c SRCS+= test_expand.c SRCS+= test_parse.c @@ -9,6 +10,7 @@ SRCS+= test_argv.c SRCS+= test_strdelim.c SRCS+= test_hpdelim.c SRCS+= test_ptimeout.c +SRCS+= test_xextendf.c # From usr.bin/ssh/Makefile.inc SRCS+= sshbuf.c @@ -23,11 +25,11 @@ SRCS+= addr.c SRCS+= addrmatch.c # From usr.bin/ssh/sshd/Makefile -SRCS+= atomicio.c cleanup.c fatal.c +SRCS+= atomicio.c cleanup.c fatal.c ssherr-libcrypto.c REGRESS_TARGETS=run-regress-${PROG} run-regress-${PROG}: ${PROG} - env ${TEST_ENV} ./${PROG} + env ${TEST_ENV} ./${PROG} ${UNITTEST_ARGS} .include diff --git a/regress/unittests/misc/test_argv.c b/regress/unittests/misc/test_argv.c index 682863e..a20a9e7 100644 --- a/regress/unittests/misc/test_argv.c +++ b/regress/unittests/misc/test_argv.c @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include diff --git a/regress/unittests/misc/test_convtime.c b/regress/unittests/misc/test_convtime.c index 4794dbd..83af8c8 100644 --- a/regress/unittests/misc/test_convtime.c +++ b/regress/unittests/misc/test_convtime.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_convtime.c,v 1.3 2022/08/11 01:57:50 djm Exp $ */ +/* $OpenBSD: test_convtime.c,v 1.4 2025/12/05 07:43:24 djm Exp $ */ /* * Regress test for misc time conversion functions. * @@ -10,9 +10,7 @@ #include #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include @@ -59,6 +57,41 @@ test_convtime(void) #endif TEST_DONE(); + TEST_START("misc_convtime_double"); + ASSERT_DOUBLE_EQ(convtime_double("0"), 0); + ASSERT_DOUBLE_EQ(convtime_double("1"), 1.0); + ASSERT_DOUBLE_EQ(convtime_double("2s"), 2.0); + ASSERT_DOUBLE_EQ(convtime_double("3m"), 180.0); + ASSERT_DOUBLE_EQ(convtime_double("1m30s"), 90.0); + ASSERT_DOUBLE_EQ(convtime_double("1.5s"), 1.5); + ASSERT_DOUBLE_EQ(convtime_double(".5s"), 0.5); + ASSERT_DOUBLE_EQ(convtime_double("0.5s"), 0.5); + ASSERT_DOUBLE_EQ(convtime_double("1.123456s"), 1.123456); + ASSERT_DOUBLE_EQ(convtime_double("1.1234567s"), 1.1234567); + ASSERT_DOUBLE_EQ(convtime_double("1.123s"), 1.123); + ASSERT_DOUBLE_EQ(convtime_double("1m0.5s"), 60.5); + ASSERT_DOUBLE_EQ(convtime_double("1m.5s"), 60.5); + ASSERT_DOUBLE_EQ(convtime_double("1.5"), 1.5); + ASSERT_DOUBLE_EQ(convtime_double("1.123456"), 1.123456); + ASSERT_DOUBLE_EQ(convtime_double("1.1234567"), 1.1234567); + /* errors */ + ASSERT_DOUBLE_LT(convtime_double(""), 0.0); + ASSERT_DOUBLE_LT(convtime_double("trout"), 0.0); + ASSERT_DOUBLE_LT(convtime_double("1.s"), 0.0); + ASSERT_DOUBLE_LT(convtime_double("0x1"), 0.0); + ASSERT_DOUBLE_LT(convtime_double("inf"), 0.0); + ASSERT_DOUBLE_LT(convtime_double("nan"), 0.0); + ASSERT_DOUBLE_LT(convtime_double("1e10"), 0.0); + ASSERT_DOUBLE_LT(convtime_double("-1"), 0.0); + ASSERT_DOUBLE_LT(convtime_double("3.w0.5s"), 0.0); + ASSERT_DOUBLE_LT(convtime_double("1.0d0.5s"), 0.0); + ASSERT_DOUBLE_LT(convtime_double("1.5m"), 0.0); + ASSERT_DOUBLE_LT(convtime_double("1.5h"), 0.0); + ASSERT_DOUBLE_LT(convtime_double("1.5d"), 0.0); + ASSERT_DOUBLE_LT(convtime_double("1.5w"), 0.0); + ASSERT_DOUBLE_LT(convtime_double("1s1.5"), 0.0); + TEST_DONE(); + /* XXX timezones/DST make verification of this tricky */ /* XXX maybe setenv TZ and tzset() to make it unambiguous? */ TEST_START("misc_parse_absolute_time"); diff --git a/regress/unittests/misc/test_expand.c b/regress/unittests/misc/test_expand.c index 6f2cd8a..a8be8d9 100644 --- a/regress/unittests/misc/test_expand.c +++ b/regress/unittests/misc/test_expand.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_expand.c,v 1.3 2021/12/14 21:25:27 deraadt Exp $ */ +/* $OpenBSD: test_expand.c,v 1.4 2025/09/15 03:00:22 djm Exp $ */ /* * Regress test for misc string expansion functions. * @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include @@ -73,17 +71,26 @@ test_expand(void) TEST_DONE(); TEST_START("percent_expand"); - ASSERT_STRING_EQ(percent_expand("%%", "%h", "foo", NULL), "%"); - ASSERT_STRING_EQ(percent_expand("%h", "h", "foo", NULL), "foo"); - ASSERT_STRING_EQ(percent_expand("%h ", "h", "foo", NULL), "foo "); - ASSERT_STRING_EQ(percent_expand(" %h", "h", "foo", NULL), " foo"); - ASSERT_STRING_EQ(percent_expand(" %h ", "h", "foo", NULL), " foo "); - ASSERT_STRING_EQ(percent_expand(" %a%b ", "a", "foo", "b", "bar", NULL), - " foobar "); +#define CHECK_ONE(val, expect) \ + ASSERT_STRING_EQ(val, expect); \ + free(val); + ret = percent_expand("%%", "%h", "foo", NULL); + CHECK_ONE(ret, "%"); + ret = percent_expand("%h", "h", "foo", NULL); + CHECK_ONE(ret, "foo"); + ret = percent_expand("%h ", "h", "foo", NULL); + CHECK_ONE(ret, "foo "); + ret = percent_expand(" %h", "h", "foo", NULL); + CHECK_ONE(ret, " foo"); + ret = percent_expand(" %h ", "h", "foo", NULL); + CHECK_ONE(ret, " foo "); + ret = percent_expand(" %a%b ", "a", "foo", "b", "bar", NULL); + CHECK_ONE(ret, " foobar "); TEST_DONE(); TEST_START("percent_dollar_expand"); - ASSERT_STRING_EQ(percent_dollar_expand("%h${FOO}", "h", "foo", NULL), - "foobar"); + ret = percent_dollar_expand("%h${FOO}", "h", "foo", NULL); + CHECK_ONE(ret, "foobar"); +#undef CHECK_ONE TEST_DONE(); } diff --git a/regress/unittests/misc/test_hpdelim.c b/regress/unittests/misc/test_hpdelim.c index d423023..626f185 100644 --- a/regress/unittests/misc/test_hpdelim.c +++ b/regress/unittests/misc/test_hpdelim.c @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include diff --git a/regress/unittests/misc/test_misc.c b/regress/unittests/misc/test_misc.c new file mode 100644 index 0000000..db0b5bb --- /dev/null +++ b/regress/unittests/misc/test_misc.c @@ -0,0 +1,475 @@ +/* + * Regress test for misc helper functions. + * + * Placed in the public domain. + */ + +#include "includes.h" + +#include +#include +#include +#include +#include + +#include "../test_helper/test_helper.h" + +#include "log.h" +#include "misc.h" +#include "xmalloc.h" + +void test_misc(void); + +static void +test_chop(void) +{ + char *s; + + TEST_START("chop newline"); + s = xstrdup("hello\n"); + ASSERT_STRING_EQ(chop(s), "hello"); + free(s); + TEST_DONE(); + + TEST_START("chop carriage return"); + s = xstrdup("hello\r"); + ASSERT_STRING_EQ(chop(s), "hello"); + free(s); + TEST_DONE(); + + TEST_START("chop CRLF"); + s = xstrdup("hello\r\n"); + ASSERT_STRING_EQ(chop(s), "hello"); + free(s); + TEST_DONE(); + + TEST_START("chop newline in middle"); + s = xstrdup("he\nllo"); + ASSERT_STRING_EQ(chop(s), "he"); + free(s); + TEST_DONE(); + + TEST_START("chop no newline"); + s = xstrdup("hello"); + ASSERT_STRING_EQ(chop(s), "hello"); + free(s); + TEST_DONE(); + + TEST_START("chop empty string"); + s = xstrdup(""); + ASSERT_STRING_EQ(chop(s), ""); + free(s); + TEST_DONE(); + + TEST_START("chop only newline"); + s = xstrdup("\n"); + ASSERT_STRING_EQ(chop(s), ""); + free(s); + TEST_DONE(); + + TEST_START("chop only CR"); + s = xstrdup("\r"); + ASSERT_STRING_EQ(chop(s), ""); + free(s); + TEST_DONE(); + + TEST_START("chop only CRLF"); + s = xstrdup("\r\n"); + ASSERT_STRING_EQ(chop(s), ""); + free(s); + TEST_DONE(); +} + +static void +test_rtrim(void) +{ + char *s; + + TEST_START("rtrim trailing space"); + s = xstrdup("hello "); + rtrim(s); + ASSERT_STRING_EQ(s, "hello"); + free(s); + TEST_DONE(); + + TEST_START("rtrim trailing tab"); + s = xstrdup("hello\t\t"); + rtrim(s); + ASSERT_STRING_EQ(s, "hello"); + free(s); + TEST_DONE(); + + TEST_START("rtrim trailing mixed whitespace"); + s = xstrdup("hello \t "); + rtrim(s); + ASSERT_STRING_EQ(s, "hello"); + free(s); + TEST_DONE(); + + TEST_START("rtrim no trailing whitespace"); + s = xstrdup("hello"); + rtrim(s); + ASSERT_STRING_EQ(s, "hello"); + free(s); + TEST_DONE(); + + TEST_START("rtrim whitespace in middle"); + s = xstrdup("he llo"); + rtrim(s); + ASSERT_STRING_EQ(s, "he llo"); + free(s); + TEST_DONE(); + + TEST_START("rtrim empty string"); + s = xstrdup(""); + rtrim(s); + ASSERT_STRING_EQ(s, ""); + free(s); + TEST_DONE(); + + TEST_START("rtrim only whitespace"); + s = xstrdup(" \t"); + rtrim(s); + ASSERT_STRING_EQ(s, ""); + free(s); + TEST_DONE(); +} + +static void +test_strprefix(void) +{ + const char *s; + + TEST_START("strprefix basic match"); + s = strprefix("hello world", "hello", 0); + ASSERT_PTR_NE(s, NULL); + ASSERT_STRING_EQ(s, " world"); + TEST_DONE(); + + TEST_START("strprefix no match"); + s = strprefix("hello world", "world", 0); + ASSERT_PTR_EQ(s, NULL); + TEST_DONE(); + + TEST_START("strprefix full match"); + s = strprefix("hello", "hello", 0); + ASSERT_PTR_NE(s, NULL); + ASSERT_STRING_EQ(s, ""); + TEST_DONE(); + + TEST_START("strprefix empty string"); + s = strprefix("", "hello", 0); + ASSERT_PTR_EQ(s, NULL); + TEST_DONE(); + + TEST_START("strprefix empty prefix"); + s = strprefix("hello", "", 0); + ASSERT_PTR_NE(s, NULL); + ASSERT_STRING_EQ(s, "hello"); + TEST_DONE(); + + TEST_START("strprefix case sensitive no match"); + s = strprefix("Hello world", "hello", 0); + ASSERT_PTR_EQ(s, NULL); + TEST_DONE(); + + TEST_START("strprefix case insensitive match"); + s = strprefix("Hello world", "hello", 1); + ASSERT_PTR_NE(s, NULL); + ASSERT_STRING_EQ(s, " world"); + TEST_DONE(); + + TEST_START("strprefix case insensitive full match"); + s = strprefix("HELLO", "hello", 1); + ASSERT_PTR_NE(s, NULL); + ASSERT_STRING_EQ(s, ""); + TEST_DONE(); +} + +static void +test_fmt_timeframe(void) +{ + TEST_START("fmt_timeframe seconds"); + ASSERT_STRING_EQ(fmt_timeframe(0), "00:00:00"); + ASSERT_STRING_EQ(fmt_timeframe(59), "00:00:59"); + ASSERT_STRING_EQ(fmt_timeframe(60), "00:01:00"); + ASSERT_STRING_EQ(fmt_timeframe(3599), "00:59:59"); + ASSERT_STRING_EQ(fmt_timeframe(3600), "01:00:00"); + ASSERT_STRING_EQ(fmt_timeframe(86399), "23:59:59"); + TEST_DONE(); + + TEST_START("fmt_timeframe days"); + ASSERT_STRING_EQ(fmt_timeframe(86400), "1d00h00m"); + ASSERT_STRING_EQ(fmt_timeframe(90061), "1d01h01m"); + ASSERT_STRING_EQ(fmt_timeframe(604799), "6d23h59m"); + TEST_DONE(); + + TEST_START("fmt_timeframe weeks"); + ASSERT_STRING_EQ(fmt_timeframe(604800), "01w0d00h"); + ASSERT_STRING_EQ(fmt_timeframe(694861), "01w1d01h"); + TEST_DONE(); +} + +static void +test_arglist(void) +{ + arglist args; + u_int i; + + memset(&args, 0, sizeof(args)); + + TEST_START("addargs initial"); + addargs(&args, "one"); + ASSERT_U_INT_EQ(args.num, 1); + ASSERT_U_INT_EQ(args.nalloc, 32); + ASSERT_PTR_NE(args.list, NULL); + ASSERT_STRING_EQ(args.list[0], "one"); + ASSERT_PTR_EQ(args.list[1], NULL); + TEST_DONE(); + + TEST_START("addargs second"); + addargs(&args, "two"); + ASSERT_U_INT_EQ(args.num, 2); + ASSERT_U_INT_EQ(args.nalloc, 32); + ASSERT_PTR_NE(args.list, NULL); + ASSERT_STRING_EQ(args.list[0], "one"); + ASSERT_STRING_EQ(args.list[1], "two"); + ASSERT_PTR_EQ(args.list[2], NULL); + TEST_DONE(); + + TEST_START("addargs with format"); + addargs(&args, "three=%d", 3); + ASSERT_U_INT_EQ(args.num, 3); + ASSERT_U_INT_EQ(args.nalloc, 32); + ASSERT_PTR_NE(args.list, NULL); + ASSERT_STRING_EQ(args.list[0], "one"); + ASSERT_STRING_EQ(args.list[1], "two"); + ASSERT_STRING_EQ(args.list[2], "three=3"); + ASSERT_PTR_EQ(args.list[3], NULL); + TEST_DONE(); + + TEST_START("replacearg middle"); + replacearg(&args, 1, "TWO!"); + ASSERT_U_INT_EQ(args.num, 3); + ASSERT_STRING_EQ(args.list[0], "one"); + ASSERT_STRING_EQ(args.list[1], "TWO!"); + ASSERT_STRING_EQ(args.list[2], "three=3"); + ASSERT_PTR_EQ(args.list[3], NULL); + TEST_DONE(); + + TEST_START("replacearg first"); + replacearg(&args, 0, "ONE!"); + ASSERT_U_INT_EQ(args.num, 3); + ASSERT_STRING_EQ(args.list[0], "ONE!"); + ASSERT_STRING_EQ(args.list[1], "TWO!"); + ASSERT_STRING_EQ(args.list[2], "three=3"); + ASSERT_PTR_EQ(args.list[3], NULL); + TEST_DONE(); + + TEST_START("replacearg last"); + replacearg(&args, 2, "THREE=3!"); + ASSERT_U_INT_EQ(args.num, 3); + ASSERT_STRING_EQ(args.list[0], "ONE!"); + ASSERT_STRING_EQ(args.list[1], "TWO!"); + ASSERT_STRING_EQ(args.list[2], "THREE=3!"); + ASSERT_PTR_EQ(args.list[3], NULL); + TEST_DONE(); + + TEST_START("replacearg with format"); + replacearg(&args, 1, "two=%d", 2); + ASSERT_U_INT_EQ(args.num, 3); + ASSERT_STRING_EQ(args.list[0], "ONE!"); + ASSERT_STRING_EQ(args.list[1], "two=2"); + ASSERT_STRING_EQ(args.list[2], "THREE=3!"); + ASSERT_PTR_EQ(args.list[3], NULL); + TEST_DONE(); + + TEST_START("addargs reallocation"); + for (i = args.num; i < 33; i++) + addargs(&args, "pad-%d", i); + ASSERT_U_INT_EQ(args.num, 33); + ASSERT_U_INT_GE(args.nalloc, 33); + ASSERT_STRING_EQ(args.list[32], "pad-32"); + ASSERT_PTR_EQ(args.list[33], NULL); + TEST_DONE(); + + TEST_START("freeargs"); + freeargs(&args); + ASSERT_U_INT_EQ(args.num, 0); + ASSERT_U_INT_EQ(args.nalloc, 0); + ASSERT_PTR_EQ(args.list, NULL); + TEST_DONE(); + + TEST_START("freeargs on NULL"); + freeargs(NULL); + TEST_DONE(); + + TEST_START("freeargs on empty"); + memset(&args, 0, sizeof(args)); + freeargs(&args); + ASSERT_U_INT_EQ(args.num, 0); + ASSERT_U_INT_EQ(args.nalloc, 0); + ASSERT_PTR_EQ(args.list, NULL); + TEST_DONE(); +} + +static void +test_tohex(void) +{ + char *hex; + + TEST_START("tohex simple"); + hex = tohex("foo", 3); + ASSERT_STRING_EQ(hex, "666f6f"); + free(hex); + TEST_DONE(); + + TEST_START("tohex with null"); + hex = tohex("a\0b", 3); + ASSERT_STRING_EQ(hex, "610062"); + free(hex); + TEST_DONE(); + + TEST_START("tohex empty"); + hex = tohex("", 0); + ASSERT_STRING_EQ(hex, ""); + free(hex); + TEST_DONE(); +} + +static void +test_lowercase(void) +{ + char *s; + + TEST_START("lowercase mixed"); + s = xstrdup("HeLlO WoRlD 123"); + lowercase(s); + ASSERT_STRING_EQ(s, "hello world 123"); + free(s); + TEST_DONE(); + + TEST_START("lowercase empty"); + s = xstrdup(""); + lowercase(s); + ASSERT_STRING_EQ(s, ""); + free(s); + TEST_DONE(); +} + +static void +test_path_absolute(void) +{ + TEST_START("path_absolute absolute"); + ASSERT_INT_EQ(path_absolute("/foo/bar"), 1); + TEST_DONE(); + + TEST_START("path_absolute relative"); + ASSERT_INT_EQ(path_absolute("foo/bar"), 0); + TEST_DONE(); + + TEST_START("path_absolute empty"); + ASSERT_INT_EQ(path_absolute(""), 0); + TEST_DONE(); +} + +static void +test_stringlist(void) +{ + char **list = NULL; + + TEST_START("stringlist_append initial"); + stringlist_append(&list, "one"); + ASSERT_PTR_NE(list, NULL); + ASSERT_STRING_EQ(list[0], "one"); + ASSERT_PTR_EQ(list[1], NULL); + TEST_DONE(); + + TEST_START("stringlist_append second"); + stringlist_append(&list, "two"); + ASSERT_PTR_NE(list, NULL); + ASSERT_STRING_EQ(list[0], "one"); + ASSERT_STRING_EQ(list[1], "two"); + ASSERT_PTR_EQ(list[2], NULL); + TEST_DONE(); + + TEST_START("stringlist_append third"); + stringlist_append(&list, "three"); + ASSERT_PTR_NE(list, NULL); + ASSERT_STRING_EQ(list[0], "one"); + ASSERT_STRING_EQ(list[1], "two"); + ASSERT_STRING_EQ(list[2], "three"); + ASSERT_PTR_EQ(list[3], NULL); + TEST_DONE(); + + TEST_START("stringlist_free"); + stringlist_free(list); + TEST_DONE(); + + TEST_START("stringlist_free NULL"); + stringlist_free(NULL); + TEST_DONE(); +} + +static void +test_skip_space(void) +{ + char *s, *p; + + TEST_START("skip_space leading spaces"); + s = p = xstrdup(" hello"); + skip_space(&p); + ASSERT_STRING_EQ(p, "hello"); + free(s); + TEST_DONE(); + + TEST_START("skip_space leading tabs"); + s = p = xstrdup("\t\thello"); + skip_space(&p); + ASSERT_STRING_EQ(p, "hello"); + free(s); + TEST_DONE(); + + TEST_START("skip_space leading mixed whitespace"); + s = p = xstrdup(" \t hello"); + skip_space(&p); + ASSERT_STRING_EQ(p, "hello"); + free(s); + TEST_DONE(); + + TEST_START("skip_space no leading whitespace"); + s = p = xstrdup("hello"); + skip_space(&p); + ASSERT_STRING_EQ(p, "hello"); + free(s); + TEST_DONE(); + + TEST_START("skip_space empty string"); + s = p = xstrdup(""); + skip_space(&p); + ASSERT_STRING_EQ(p, ""); + free(s); + TEST_DONE(); + + TEST_START("skip_space only whitespace"); + s = p = xstrdup(" \t "); + skip_space(&p); + ASSERT_STRING_EQ(p, ""); + free(s); + TEST_DONE(); +} + +void +test_misc(void) +{ + test_chop(); + test_rtrim(); + test_strprefix(); + test_fmt_timeframe(); + test_arglist(); + test_tohex(); + test_lowercase(); + test_path_absolute(); + test_stringlist(); + test_skip_space(); +} diff --git a/regress/unittests/misc/test_parse.c b/regress/unittests/misc/test_parse.c index 1f1ea31..cbffbe0 100644 --- a/regress/unittests/misc/test_parse.c +++ b/regress/unittests/misc/test_parse.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_parse.c,v 1.2 2021/12/14 21:25:27 deraadt Exp $ */ +/* $OpenBSD: test_parse.c,v 1.3 2025/06/12 10:09:39 dtucker Exp $ */ /* * Regress test for misc user/host/URI parsing functions. * @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include @@ -29,6 +27,7 @@ test_parse(void) char *user, *host, *path; TEST_START("misc_parse_user_host_path"); + user = host = path = NULL; ASSERT_INT_EQ(parse_user_host_path("someuser@some.host:some/path", &user, &host, &path), 0); ASSERT_STRING_EQ(user, "someuser"); @@ -38,6 +37,7 @@ test_parse(void) TEST_DONE(); TEST_START("misc_parse_user_ipv4_path"); + user = host = path = NULL; ASSERT_INT_EQ(parse_user_host_path("someuser@1.22.33.144:some/path", &user, &host, &path), 0); ASSERT_STRING_EQ(user, "someuser"); @@ -47,6 +47,7 @@ test_parse(void) TEST_DONE(); TEST_START("misc_parse_user_[ipv4]_path"); + user = host = path = NULL; ASSERT_INT_EQ(parse_user_host_path("someuser@[1.22.33.144]:some/path", &user, &host, &path), 0); ASSERT_STRING_EQ(user, "someuser"); @@ -56,6 +57,7 @@ test_parse(void) TEST_DONE(); TEST_START("misc_parse_user_[ipv4]_nopath"); + user = host = path = NULL; ASSERT_INT_EQ(parse_user_host_path("someuser@[1.22.33.144]:", &user, &host, &path), 0); ASSERT_STRING_EQ(user, "someuser"); @@ -65,6 +67,7 @@ test_parse(void) TEST_DONE(); TEST_START("misc_parse_user_ipv6_path"); + user = host = path = NULL; ASSERT_INT_EQ(parse_user_host_path("someuser@[::1]:some/path", &user, &host, &path), 0); ASSERT_STRING_EQ(user, "someuser"); @@ -74,6 +77,7 @@ test_parse(void) TEST_DONE(); TEST_START("misc_parse_uri"); + user = host = path = NULL; ASSERT_INT_EQ(parse_uri("ssh", "ssh://someuser@some.host:22/some/path", &user, &host, &port, &path), 0); ASSERT_STRING_EQ(user, "someuser"); diff --git a/regress/unittests/misc/test_ptimeout.c b/regress/unittests/misc/test_ptimeout.c index cc58ee8..f56e889 100644 --- a/regress/unittests/misc/test_ptimeout.c +++ b/regress/unittests/misc/test_ptimeout.c @@ -9,14 +9,10 @@ #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include -#ifdef HAVE_POLL_H -# include -#endif +#include #include #include "../test_helper/test_helper.h" diff --git a/regress/unittests/misc/test_strdelim.c b/regress/unittests/misc/test_strdelim.c index f7bea4b..ae0f715 100644 --- a/regress/unittests/misc/test_strdelim.c +++ b/regress/unittests/misc/test_strdelim.c @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include diff --git a/regress/unittests/misc/test_xextendf.c b/regress/unittests/misc/test_xextendf.c new file mode 100644 index 0000000..3c1ee8b --- /dev/null +++ b/regress/unittests/misc/test_xextendf.c @@ -0,0 +1,89 @@ +/* $OpenBSD: test_xextendf.c,v 1.1 2025/09/02 11:04:58 djm Exp $ */ +/* + * Regress test for misc xextendf() function. + * + * Placed in the public domain. + */ + +#include "includes.h" + +#include +#include +#include +#include +#include + +#include "../test_helper/test_helper.h" + +#include "log.h" +#include "misc.h" +#include "xmalloc.h" + +void test_xextendf(void); + +void +test_xextendf(void) +{ + char *s = NULL; + + TEST_START("xextendf NULL string"); + xextendf(&s, ",", "hello"); + ASSERT_STRING_EQ(s, "hello"); + free(s); + s = NULL; + TEST_DONE(); + + TEST_START("xextendf empty string"); + s = xstrdup(""); + xextendf(&s, ",", "world"); + ASSERT_STRING_EQ(s, "world"); + free(s); + s = NULL; + TEST_DONE(); + + TEST_START("xextendf append to string"); + s = xstrdup("foo"); + xextendf(&s, ",", "bar"); + ASSERT_STRING_EQ(s, "foo,bar"); + free(s); + s = NULL; + TEST_DONE(); + + TEST_START("xextendf append with NULL separator"); + s = xstrdup("foo"); + xextendf(&s, NULL, "bar"); + ASSERT_STRING_EQ(s, "foobar"); + free(s); + s = NULL; + TEST_DONE(); + + TEST_START("xextendf append with empty separator"); + s = xstrdup("foo"); + xextendf(&s, "", "bar"); + ASSERT_STRING_EQ(s, "foobar"); + free(s); + s = NULL; + TEST_DONE(); + + TEST_START("xextendf with format string"); + s = xstrdup("start"); + xextendf(&s, ":", "s=%s,d=%d", "string", 123); + ASSERT_STRING_EQ(s, "start:s=string,d=123"); + free(s); + s = NULL; + TEST_DONE(); + + TEST_START("xextendf multiple appends"); + s = NULL; + xextendf(&s, ",", "one"); + ASSERT_STRING_EQ(s, "one"); + xextendf(&s, ",", "two"); + ASSERT_STRING_EQ(s, "one,two"); + xextendf(&s, ":", "three=%d", 3); + ASSERT_STRING_EQ(s, "one,two:three=3"); + xextendf(&s, NULL, "four"); + ASSERT_STRING_EQ(s, "one,two:three=3four"); + free(s); + s = NULL; + TEST_DONE(); +} diff --git a/regress/unittests/misc/tests.c b/regress/unittests/misc/tests.c index 3269954..a71dde7 100644 --- a/regress/unittests/misc/tests.c +++ b/regress/unittests/misc/tests.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tests.c,v 1.10 2023/01/06 02:59:50 djm Exp $ */ +/* $OpenBSD: tests.c,v 1.13 2025/09/04 00:34:17 djm Exp $ */ /* * Regress test for misc helper functions. * @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include @@ -27,6 +25,8 @@ void test_argv(void); void test_strdelim(void); void test_hpdelim(void); void test_ptimeout(void); +void test_xextendf(void); +void test_misc(void); void tests(void) @@ -38,4 +38,12 @@ tests(void) test_strdelim(); test_hpdelim(); test_ptimeout(); + test_xextendf(); + test_misc(); +} + +void +benchmarks(void) +{ + printf("no benchmarks\n"); } diff --git a/regress/unittests/sshbuf/Makefile b/regress/unittests/sshbuf/Makefile index a8ddfaf..2710624 100644 --- a/regress/unittests/sshbuf/Makefile +++ b/regress/unittests/sshbuf/Makefile @@ -1,6 +1,4 @@ -# $OpenBSD: Makefile,v 1.10 2021/01/09 12:24:31 dtucker Exp $ - -# $OpenBSD: Makefile,v 1.8 2020/01/26 00:09:50 djm Exp $ +# $OpenBSD: Makefile,v 1.11 2026/02/06 23:39:14 dtucker Exp $ PROG=test_sshbuf SRCS=tests.c @@ -15,7 +13,7 @@ SRCS+=test_sshbuf_fixed.c # From usr.bin/ssh SRCS+=sshbuf-getput-basic.c sshbuf-getput-crypto.c sshbuf-misc.c sshbuf.c SRCS+=sshbuf-io.c atomicio.c misc.c xmalloc.c log.c fatal.c ssherr.c cleanup.c -SRCS+=match.c addr.c addrmatch.c +SRCS+=match.c addr.c addrmatch.c ssherr-libcrypto.c run-regress-${PROG}: ${PROG} env ${TEST_ENV} ./${PROG} ${UNITTEST_ARGS} diff --git a/regress/unittests/sshbuf/test_sshbuf.c b/regress/unittests/sshbuf/test_sshbuf.c index e22b390..3e165d4 100644 --- a/regress/unittests/sshbuf/test_sshbuf.c +++ b/regress/unittests/sshbuf/test_sshbuf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_sshbuf.c,v 1.2 2021/12/14 21:25:27 deraadt Exp $ */ +/* $OpenBSD: test_sshbuf.c,v 1.3 2025/12/30 00:12:58 djm Exp $ */ /* * Regress test for sshbuf.h buffer API * @@ -10,9 +10,7 @@ #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include @@ -30,7 +28,8 @@ void sshbuf_tests(void); void sshbuf_tests(void) { - struct sshbuf *p1; + struct sshbuf *p1, *p2, *p3; + u_int v32; const u_char *cdp; u_char *dp; size_t sz; @@ -240,4 +239,38 @@ sshbuf_tests(void) ASSERT_SIZE_T_EQ(sshbuf_avail(p1), 1223); sshbuf_free(p1); TEST_DONE(); + + TEST_START("sshbuf_consume_upto_child"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + p2 = sshbuf_new(); + ASSERT_PTR_NE(p2, NULL); + /* Unrelated buffers */ + ASSERT_INT_EQ(sshbuf_consume_upto_child(p1, p2), + SSH_ERR_INVALID_ARGUMENT); + /* Simple success case */ + ASSERT_INT_EQ(sshbuf_put_u32(p1, 0xdeadbeef), 0); + ASSERT_INT_EQ(sshbuf_put_u32(p1, 0x01020304), 0); + ASSERT_INT_EQ(sshbuf_put_u32(p1, 0xfeedface), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 12); + p3 = sshbuf_fromb(p1); + ASSERT_PTR_NE(p3, NULL); + ASSERT_INT_EQ(sshbuf_get_u32(p3, &v32), 0); + ASSERT_U32_EQ(v32, 0xdeadbeef); + ASSERT_SIZE_T_EQ(sshbuf_len(p3), 8); + ASSERT_INT_EQ(sshbuf_consume_upto_child(p1, p3), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), sshbuf_len(p3)); + ASSERT_PTR_EQ(sshbuf_ptr(p1), sshbuf_ptr(p3)); + sshbuf_free(p3); + /* Parent already consumed past child */ + p3 = sshbuf_fromb(p1); + ASSERT_PTR_NE(p3, NULL); + ASSERT_INT_EQ(sshbuf_get_u32(p1, &v32), 0); + ASSERT_U32_EQ(v32, 0x01020304); + ASSERT_INT_EQ(sshbuf_consume_upto_child(p1, p3), + SSH_ERR_INVALID_ARGUMENT); + sshbuf_free(p1); + sshbuf_free(p2); + sshbuf_free(p3); + TEST_DONE(); } diff --git a/regress/unittests/sshbuf/test_sshbuf_fixed.c b/regress/unittests/sshbuf/test_sshbuf_fixed.c index dff77f0..cc05025 100644 --- a/regress/unittests/sshbuf/test_sshbuf_fixed.c +++ b/regress/unittests/sshbuf/test_sshbuf_fixed.c @@ -10,9 +10,7 @@ #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include diff --git a/regress/unittests/sshbuf/test_sshbuf_fuzz.c b/regress/unittests/sshbuf/test_sshbuf_fuzz.c index c0b809d..0d80830 100644 --- a/regress/unittests/sshbuf/test_sshbuf_fuzz.c +++ b/regress/unittests/sshbuf/test_sshbuf_fuzz.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_sshbuf_fuzz.c,v 1.4 2021/12/18 06:53:59 anton Exp $ */ +/* $OpenBSD: test_sshbuf_fuzz.c,v 1.5 2026/03/06 06:57:33 dtucker Exp $ */ /* * Regress test for sshbuf.h buffer API * @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include @@ -30,7 +28,7 @@ sshbuf_fuzz_tests(void) struct sshbuf *p1; u_char *dp; size_t sz, sz2, i, ntests = NUM_FUZZ_TESTS; - u_int32_t r; + uint32_t r; int ret; if (test_is_fast()) diff --git a/regress/unittests/sshbuf/test_sshbuf_getput_basic.c b/regress/unittests/sshbuf/test_sshbuf_getput_basic.c index 3da413e..1e479a4 100644 --- a/regress/unittests/sshbuf/test_sshbuf_getput_basic.c +++ b/regress/unittests/sshbuf/test_sshbuf_getput_basic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_sshbuf_getput_basic.c,v 1.3 2021/12/14 21:25:27 deraadt Exp $ */ +/* $OpenBSD: test_sshbuf_getput_basic.c,v 1.7 2026/03/06 06:57:33 dtucker Exp $ */ /* * Regress test for sshbuf.h buffer API * @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include @@ -29,9 +27,9 @@ sshbuf_getput_basic_tests(void) u_char *d, d2[32], x[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x00, 0x99 }; - u_int64_t v64; - u_int32_t v32; - u_int16_t v16; + uint64_t v64; + uint32_t v32; + uint16_t v16; u_char v8; size_t s; char *s2; @@ -576,6 +574,7 @@ sshbuf_getput_basic_tests(void) ASSERT_PTR_NE(s2, NULL); ASSERT_STRING_EQ(s2, "00000000000000000000"); sshbuf_free(p1); + free(s2); TEST_DONE(); TEST_START("sshbuf_poke_u32"); @@ -610,6 +609,7 @@ sshbuf_getput_basic_tests(void) ASSERT_PTR_NE(s2, NULL); ASSERT_STRING_EQ(s2, "00000000000000000000"); sshbuf_free(p1); + free(s2); TEST_DONE(); TEST_START("sshbuf_poke_u16"); @@ -644,6 +644,7 @@ sshbuf_getput_basic_tests(void) ASSERT_PTR_NE(s2, NULL); ASSERT_STRING_EQ(s2, "00000000000000000000"); sshbuf_free(p1); + free(s2); TEST_DONE(); TEST_START("sshbuf_poke_u8"); @@ -674,6 +675,7 @@ sshbuf_getput_basic_tests(void) ASSERT_PTR_NE(s2, NULL); ASSERT_STRING_EQ(s2, "00000000000000000000"); sshbuf_free(p1); + free(s2); TEST_DONE(); TEST_START("sshbuf_poke"); @@ -708,5 +710,121 @@ sshbuf_getput_basic_tests(void) ASSERT_PTR_NE(s2, NULL); ASSERT_STRING_EQ(s2, "00000000000000000000"); sshbuf_free(p1); + free(s2); + TEST_DONE(); + + TEST_START("sshbuf_get_nulterminated_string"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put(p1, "hello", 5), 0); + ASSERT_INT_EQ(sshbuf_put_u8(p1, 0), 0); /* hello\0 */ + ASSERT_INT_EQ(sshbuf_put(p1, "there", 5), 0); /* hello\0there */ + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 11); + /* short maxlen */ + ASSERT_INT_EQ(sshbuf_get_nulterminated_string(p1, 1, &s2, &s), + SSH_ERR_INVALID_FORMAT); + ASSERT_PTR_EQ(s2, NULL); + ASSERT_SIZE_T_EQ(s, 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 11); /* Buffer should be unchanged */ + ASSERT_INT_EQ(sshbuf_get_nulterminated_string(p1, 4, &s2, &s), + SSH_ERR_INVALID_FORMAT); + ASSERT_PTR_EQ(s2, NULL); + ASSERT_SIZE_T_EQ(s, 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 11); /* Buffer should be unchanged */ + /* minimum usable maxlen */ + ASSERT_INT_EQ(sshbuf_get_nulterminated_string(p1, 5, &s2, &s), 0); + ASSERT_STRING_EQ(s2, "hello"); + ASSERT_SIZE_T_EQ(s, 5); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 5); /* "there" remains */ + free(s2); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_get_nulterminated_string un-terminated string"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put(p1, "there", 5), 0); /* "there" */ + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 5); + ASSERT_INT_EQ(sshbuf_get_nulterminated_string(p1, 5, &s2, &s), + SSH_ERR_INVALID_FORMAT); + ASSERT_PTR_EQ(s2, NULL); + ASSERT_SIZE_T_EQ(s, 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 5); /* Buffer should be unchanged */ + ASSERT_INT_EQ(sshbuf_get_nulterminated_string(p1, 6, &s2, &s), + SSH_ERR_MESSAGE_INCOMPLETE); + ASSERT_PTR_EQ(s2, NULL); + ASSERT_SIZE_T_EQ(s, 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 5); /* Buffer should be unchanged */ + ASSERT_INT_EQ(sshbuf_get_nulterminated_string(p1, SIZE_MAX, &s2, &s), + SSH_ERR_MESSAGE_INCOMPLETE); + ASSERT_PTR_EQ(s2, NULL); + ASSERT_SIZE_T_EQ(s, 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 5); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_get_nulterminated_string subsequent strings"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put(p1, "there", 5), 0); + ASSERT_INT_EQ(sshbuf_put_u8(p1, 0), 0); /* "there\0" */ + ASSERT_INT_EQ(sshbuf_put(p1, "it is", 5), 0); + ASSERT_INT_EQ(sshbuf_put_u8(p1, 0), 0); /* "it is\0" */ + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 12); + ASSERT_INT_EQ(sshbuf_get_nulterminated_string(p1, 6, &s2, &s), 0); + ASSERT_STRING_EQ(s2, "there"); + ASSERT_SIZE_T_EQ(s, 5); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 6); + free(s2); + ASSERT_INT_EQ(sshbuf_get_nulterminated_string(p1, SIZE_MAX, &s2, &s), 0); + ASSERT_STRING_EQ(s2, "it is"); + ASSERT_SIZE_T_EQ(s, 5); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); + free(s2); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_get_nulterminated_string empty buffer"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_get_nulterminated_string(p1, SIZE_MAX, &s2, &s), + SSH_ERR_MESSAGE_INCOMPLETE); + ASSERT_PTR_EQ(s2, NULL); + ASSERT_SIZE_T_EQ(s, 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_get_nulterminated_string: single nul byte"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u8(p1, 0), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); + ASSERT_INT_EQ(sshbuf_get_nulterminated_string(p1, 0, &s2, &s), 0); + ASSERT_STRING_EQ(s2, ""); + ASSERT_SIZE_T_EQ(s, 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); + free(s2); + sshbuf_free(p1); + TEST_DONE(); + + TEST_START("sshbuf_get_nulterminated_string starts with nul"); + p1 = sshbuf_new(); + ASSERT_PTR_NE(p1, NULL); + ASSERT_INT_EQ(sshbuf_put_u8(p1, 0), 0); + ASSERT_INT_EQ(sshbuf_put(p1, "hello", 5), 0); + ASSERT_INT_EQ(sshbuf_put_u8(p1, 0), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 7); + ASSERT_INT_EQ(sshbuf_get_nulterminated_string(p1, SIZE_MAX, &s2, &s), 0); + ASSERT_STRING_EQ(s2, ""); + ASSERT_SIZE_T_EQ(s, 0); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 6); + free(s2); + ASSERT_INT_EQ(sshbuf_get_nulterminated_string(p1, SIZE_MAX, &s2, &s), 0); + ASSERT_STRING_EQ(s2, "hello"); + ASSERT_SIZE_T_EQ(s, 5); + ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); + free(s2); + sshbuf_free(p1); TEST_DONE(); } diff --git a/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c b/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c index e3620e9..1d83ffd 100644 --- a/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c +++ b/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_sshbuf_getput_crypto.c,v 1.3 2021/12/14 21:25:27 deraadt Exp $ */ +/* $OpenBSD: test_sshbuf_getput_crypto.c,v 1.5 2026/03/06 06:57:33 dtucker Exp $ */ /* * Regress test for sshbuf.h buffer API * @@ -11,9 +11,7 @@ #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include @@ -22,6 +20,7 @@ #ifdef OPENSSL_HAS_NISTP256 # include #endif +#include "openbsd-compat/openssl-compat.h" #include "../test_helper/test_helper.h" #include "ssherr.h" @@ -83,7 +82,7 @@ sshbuf_getput_crypto_tests(void) ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_bignum2(p1, bn), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 4); - ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), (u_int32_t)BN_num_bytes(bn)); + ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), (uint32_t)BN_num_bytes(bn)); ASSERT_MEM_EQ(sshbuf_ptr(p1) + 4, expbn1, sizeof(expbn1)); BN_free(bn); sshbuf_free(p1); @@ -107,7 +106,7 @@ sshbuf_getput_crypto_tests(void) ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put_bignum2(p1, bn), 0); ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 4 + 1); /* MSB */ - ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), (u_int32_t)BN_num_bytes(bn) + 1); + ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), (uint32_t)BN_num_bytes(bn) + 1); ASSERT_U8_EQ(*(sshbuf_ptr(p1) + 4), 0x00); ASSERT_MEM_EQ(sshbuf_ptr(p1) + 5, expbn2, sizeof(expbn2)); BN_free(bn); @@ -230,7 +229,7 @@ sshbuf_getput_crypto_tests(void) ASSERT_PTR_NE(ecp, NULL); MKBN(ec256_x, bn_x); MKBN(ec256_y, bn_y); - ASSERT_INT_EQ(EC_POINT_set_affine_coordinates_GFp( + ASSERT_INT_EQ(EC_POINT_set_affine_coordinates( EC_KEY_get0_group(eck), ecp, bn_x, bn_y, NULL), 1); ASSERT_INT_EQ(EC_KEY_set_public_key(eck, ecp), 1); BN_free(bn_x); @@ -259,7 +258,7 @@ sshbuf_getput_crypto_tests(void) bn_y = BN_new(); ASSERT_PTR_NE(bn_x, NULL); ASSERT_PTR_NE(bn_y, NULL); - ASSERT_INT_EQ(EC_POINT_get_affine_coordinates_GFp( + ASSERT_INT_EQ(EC_POINT_get_affine_coordinates( EC_KEY_get0_group(eck), EC_KEY_get0_public_key(eck), bn_x, bn_y, NULL), 1); MKBN(ec256_x, bn); diff --git a/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c b/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c index 3b48958..7b2ffce 100644 --- a/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c +++ b/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_sshbuf_getput_fuzz.c,v 1.5 2021/12/14 21:25:27 deraadt Exp $ */ +/* $OpenBSD: test_sshbuf_getput_fuzz.c,v 1.7 2026/03/06 06:57:33 dtucker Exp $ */ /* * Regress test for sshbuf.h buffer API * @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include @@ -41,30 +39,30 @@ attempt_parse_blob(u_char *blob, size_t len) #endif /* WITH_OPENSSL */ u_char *s; size_t l; - u_int8_t u8; - u_int16_t u16; - u_int32_t u32; - u_int64_t u64; + uint8_t u8; + uint16_t u16; + uint32_t u32; + uint64_t u64; p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put(p1, blob, len), 0); - sshbuf_get_u8(p1, &u8); - sshbuf_get_u16(p1, &u16); - sshbuf_get_u32(p1, &u32); - sshbuf_get_u64(p1, &u64); + ASSERT_INT_EQ(sshbuf_get_u8(p1, &u8), 0); + ASSERT_INT_EQ(sshbuf_get_u16(p1, &u16), 0); + ASSERT_INT_EQ(sshbuf_get_u32(p1, &u32), 0); + ASSERT_INT_EQ(sshbuf_get_u64(p1, &u64), 0); if (sshbuf_get_string(p1, &s, &l) == 0) { bzero(s, l); free(s); } #ifdef WITH_OPENSSL bn = NULL; - sshbuf_get_bignum2(p1, &bn); + ASSERT_INT_EQ(sshbuf_get_bignum2(p1, &bn), 0); BN_clear_free(bn); #if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) eck = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); ASSERT_PTR_NE(eck, NULL); - sshbuf_get_eckey(p1, eck); + ASSERT_INT_EQ(sshbuf_get_eckey(p1, eck), 0); EC_KEY_free(eck); #endif /* defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) */ #endif /* WITH_OPENSSL */ diff --git a/regress/unittests/sshbuf/test_sshbuf_misc.c b/regress/unittests/sshbuf/test_sshbuf_misc.c index 249ecf2..6b5b380 100644 --- a/regress/unittests/sshbuf/test_sshbuf_misc.c +++ b/regress/unittests/sshbuf/test_sshbuf_misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_sshbuf_misc.c,v 1.5 2021/12/14 21:25:27 deraadt Exp $ */ +/* $OpenBSD: test_sshbuf_misc.c,v 1.7 2025/09/15 03:00:22 djm Exp $ */ /* * Regress test for sshbuf.h buffer API * @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include @@ -22,11 +20,11 @@ void sshbuf_misc_tests(void); -void -sshbuf_misc_tests(void) +static void +test_sshbuf_dump(void) { struct sshbuf *p1; - char tmp[512], msg[] = "imploring ping silence ping over", *p; + char tmp[512]; FILE *out; size_t sz; @@ -48,6 +46,13 @@ sshbuf_misc_tests(void) fclose(out); sshbuf_free(p1); TEST_DONE(); +} + +static void +test_sshbuf_dtob16(void) +{ + struct sshbuf *p1; + char *p; TEST_START("sshbuf_dtob16"); p1 = sshbuf_new(); @@ -59,6 +64,13 @@ sshbuf_misc_tests(void) free(p); sshbuf_free(p1); TEST_DONE(); +} + +static void +test_sshbuf_dtob64_string(void) +{ + struct sshbuf *p1; + char *p; TEST_START("sshbuf_dtob64_string len 1"); p1 = sshbuf_new(); @@ -107,6 +119,12 @@ sshbuf_misc_tests(void) free(p); sshbuf_free(p1); TEST_DONE(); +} + +static void +test_sshbuf_b64tod(void) +{ + struct sshbuf *p1; TEST_START("sshbuf_b64tod len 1"); p1 = sshbuf_new(); @@ -134,6 +152,13 @@ sshbuf_misc_tests(void) ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), 0xd00fd00f); sshbuf_free(p1); TEST_DONE(); +} + +static void +test_sshbuf_dup_string(void) +{ + struct sshbuf *p1; + char *p; TEST_START("sshbuf_dup_string"); p1 = sshbuf_new(); @@ -163,6 +188,13 @@ sshbuf_misc_tests(void) ASSERT_PTR_EQ(p, NULL); sshbuf_free(p1); TEST_DONE(); +} + +static void +test_sshbuf_cmp(void) +{ + struct sshbuf *p1; + char msg[] = "imploring ping silence ping over"; TEST_START("sshbuf_cmp"); p1 = sshbuf_from(msg, sizeof(msg) - 1); @@ -182,7 +214,16 @@ sshbuf_misc_tests(void) ASSERT_INT_EQ(sshbuf_cmp(p1, 1000, "silence", 7), SSH_ERR_MESSAGE_INCOMPLETE); ASSERT_INT_EQ(sshbuf_cmp(p1, 0, msg, sizeof(msg) - 1), 0); + sshbuf_free(p1); TEST_DONE(); +} + +static void +test_sshbuf_find(void) +{ + struct sshbuf *p1; + char msg[] = "imploring ping silence ping over"; + size_t sz; TEST_START("sshbuf_find"); p1 = sshbuf_from(msg, sizeof(msg) - 1); @@ -212,6 +253,174 @@ sshbuf_misc_tests(void) SSH_ERR_MESSAGE_INCOMPLETE); ASSERT_INT_EQ(sshbuf_find(p1, 0, msg + 1, sizeof(msg) - 2, &sz), 0); ASSERT_SIZE_T_EQ(sz, 1); + sshbuf_free(p1); + TEST_DONE(); +} + +static void +test_sshbuf_equals(void) +{ + struct sshbuf *b1, *b2; + + TEST_START("sshbuf_equals identical"); + b1 = sshbuf_new(); + b2 = sshbuf_new(); + ASSERT_PTR_NE(b1, NULL); + ASSERT_PTR_NE(b2, NULL); + ASSERT_INT_EQ(sshbuf_put(b1, "hello", 5), 0); + ASSERT_INT_EQ(sshbuf_put(b2, "hello", 5), 0); + ASSERT_INT_EQ(sshbuf_equals(b1, b2), 0); + sshbuf_free(b1); + sshbuf_free(b2); + TEST_DONE(); + + TEST_START("sshbuf_equals different content"); + b1 = sshbuf_new(); + b2 = sshbuf_new(); + ASSERT_PTR_NE(b1, NULL); + ASSERT_PTR_NE(b2, NULL); + ASSERT_INT_EQ(sshbuf_put(b1, "hello", 5), 0); + ASSERT_INT_EQ(sshbuf_put(b2, "world", 5), 0); + ASSERT_INT_EQ(sshbuf_equals(b1, b2), SSH_ERR_INVALID_FORMAT); + sshbuf_free(b1); + sshbuf_free(b2); + TEST_DONE(); + + TEST_START("sshbuf_equals different length"); + b1 = sshbuf_new(); + b2 = sshbuf_new(); + ASSERT_PTR_NE(b1, NULL); + ASSERT_PTR_NE(b2, NULL); + ASSERT_INT_EQ(sshbuf_put(b1, "hello", 5), 0); + ASSERT_INT_EQ(sshbuf_put(b2, "hell", 4), 0); + ASSERT_INT_EQ(sshbuf_equals(b1, b2), SSH_ERR_MESSAGE_INCOMPLETE); + sshbuf_free(b1); + sshbuf_free(b2); + TEST_DONE(); + + TEST_START("sshbuf_equals empty buffers"); + b1 = sshbuf_new(); + b2 = sshbuf_new(); + ASSERT_PTR_NE(b1, NULL); + ASSERT_PTR_NE(b2, NULL); + ASSERT_INT_EQ(sshbuf_equals(b1, b2), 0); + sshbuf_free(b1); + sshbuf_free(b2); + TEST_DONE(); + + TEST_START("sshbuf_equals one empty buffer"); + b1 = sshbuf_new(); + b2 = sshbuf_new(); + ASSERT_PTR_NE(b1, NULL); + ASSERT_PTR_NE(b2, NULL); + ASSERT_INT_EQ(sshbuf_put(b1, "hello", 5), 0); + ASSERT_INT_EQ(sshbuf_equals(b1, b2), SSH_ERR_MESSAGE_INCOMPLETE); + sshbuf_free(b1); + sshbuf_free(b2); + TEST_DONE(); + + TEST_START("sshbuf_equals buffer to self"); + b1 = sshbuf_new(); + ASSERT_PTR_NE(b1, NULL); + ASSERT_INT_EQ(sshbuf_put(b1, "hello", 5), 0); + ASSERT_INT_EQ(sshbuf_equals(b1, b1), 0); + sshbuf_free(b1); TEST_DONE(); } +static void +test_sshbuf_dtourlb64(void) +{ + struct sshbuf *b, *b64; + char *s; + /* From RFC4648 */ + const u_char test_vec1[] = {0x14, 0xfb, 0x9c, 0x03, 0xd9, 0x7e}; + const u_char test_vec2[] = {0xff, 0xff, 0xff}; + const u_char test_vec3[] = {0xfb}; + + TEST_START("sshbuf_dtourlb64 empty"); + b = sshbuf_new(); + b64 = sshbuf_new(); + ASSERT_PTR_NE(b, NULL); + ASSERT_PTR_NE(b64, NULL); + ASSERT_INT_EQ(sshbuf_dtourlb64(b, b64, 0), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(b64), 0); + sshbuf_free(b); + sshbuf_free(b64); + TEST_DONE(); + + TEST_START("sshbuf_dtourlb64 no special chars"); + b = sshbuf_new(); + b64 = sshbuf_new(); + ASSERT_PTR_NE(b, NULL); + ASSERT_PTR_NE(b64, NULL); + ASSERT_INT_EQ(sshbuf_put(b, "hello", 5), 0); + ASSERT_INT_EQ(sshbuf_dtourlb64(b, b64, 0), 0); + s = sshbuf_dup_string(b64); + ASSERT_PTR_NE(s, NULL); + ASSERT_STRING_EQ(s, "aGVsbG8"); + free(s); + sshbuf_free(b); + sshbuf_free(b64); + TEST_DONE(); + + TEST_START("sshbuf_dtourlb64 with '+' char"); + b = sshbuf_new(); + b64 = sshbuf_new(); + ASSERT_PTR_NE(b, NULL); + ASSERT_PTR_NE(b64, NULL); + ASSERT_INT_EQ(sshbuf_put(b, test_vec1, sizeof(test_vec1)), 0); + ASSERT_INT_EQ(sshbuf_dtourlb64(b, b64, 0), 0); + s = sshbuf_dup_string(b64); + ASSERT_PTR_NE(s, NULL); + ASSERT_STRING_EQ(s, "FPucA9l-"); + free(s); + sshbuf_free(b); + sshbuf_free(b64); + TEST_DONE(); + + TEST_START("sshbuf_dtourlb64 with '/' char"); + b = sshbuf_new(); + b64 = sshbuf_new(); + ASSERT_PTR_NE(b, NULL); + ASSERT_PTR_NE(b64, NULL); + ASSERT_INT_EQ(sshbuf_put(b, test_vec2, sizeof(test_vec2)), 0); + ASSERT_INT_EQ(sshbuf_dtourlb64(b, b64, 0), 0); + s = sshbuf_dup_string(b64); + ASSERT_PTR_NE(s, NULL); + ASSERT_STRING_EQ(s, "____"); + free(s); + sshbuf_free(b); + sshbuf_free(b64); + TEST_DONE(); + + TEST_START("sshbuf_dtourlb64 with padding removed"); + b = sshbuf_new(); + b64 = sshbuf_new(); + ASSERT_PTR_NE(b, NULL); + ASSERT_PTR_NE(b64, NULL); + ASSERT_INT_EQ(sshbuf_put(b, test_vec3, sizeof(test_vec3)), 0); + ASSERT_INT_EQ(sshbuf_dtourlb64(b, b64, 0), 0); + s = sshbuf_dup_string(b64); + ASSERT_PTR_NE(s, NULL); + ASSERT_STRING_EQ(s, "-w"); + free(s); + sshbuf_free(b); + sshbuf_free(b64); + TEST_DONE(); +} + +void +sshbuf_misc_tests(void) +{ + test_sshbuf_dump(); + test_sshbuf_dtob16(); + test_sshbuf_dtob64_string(); + test_sshbuf_b64tod(); + test_sshbuf_dup_string(); + test_sshbuf_cmp(); + test_sshbuf_find(); + test_sshbuf_equals(); + test_sshbuf_dtourlb64(); +} + diff --git a/regress/unittests/sshbuf/tests.c b/regress/unittests/sshbuf/tests.c index 29916a1..95a34a8 100644 --- a/regress/unittests/sshbuf/tests.c +++ b/regress/unittests/sshbuf/tests.c @@ -1,10 +1,14 @@ -/* $OpenBSD: tests.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */ +/* $OpenBSD: tests.c,v 1.2 2025/04/15 04:00:42 djm Exp $ */ /* * Regress test for sshbuf.h buffer API * * Placed in the public domain */ +#include "includes.h" + +#include + #include "../test_helper/test_helper.h" void sshbuf_tests(void); @@ -28,3 +32,9 @@ tests(void) sshbuf_getput_fuzz_tests(); sshbuf_fixed(); } + +void +benchmarks(void) +{ + printf("no benchmarks\n"); +} diff --git a/regress/unittests/sshkey/Makefile b/regress/unittests/sshkey/Makefile index cd0f44d..083175c 100644 --- a/regress/unittests/sshkey/Makefile +++ b/regress/unittests/sshkey/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.12 2023/01/15 23:35:10 djm Exp $ +# $OpenBSD: Makefile,v 1.16 2026/02/06 23:39:14 dtucker Exp $ PROG=test_sshkey SRCS=tests.c test_sshkey.c test_file.c test_fuzz.c common.c @@ -6,16 +6,16 @@ SRCS=tests.c test_sshkey.c test_file.c test_fuzz.c common.c # From usr.bin/ssh SRCS+=sshbuf-getput-basic.c sshbuf-getput-crypto.c sshbuf-misc.c sshbuf.c SRCS+=sshbuf-io.c atomicio.c sshkey.c authfile.c cipher.c log.c ssh-rsa.c -SRCS+=ssh-dss.c ssh-ecdsa.c ssh-ed25519.c mac.c umac.c umac128.c hmac.c misc.c +SRCS+=ssh-ecdsa.c ssh-ed25519.c mac.c umac.c umac128.c hmac.c misc.c SRCS+=ssherr.c uidswap.c cleanup.c xmalloc.c match.c krl.c fatal.c SRCS+=addr.c addrmatch.c bitmap.c -SRCS+=ed25519.c hash.c SRCS+=cipher-chachapoly.c chacha.c poly1305.c ssh-ecdsa-sk.c ssh-sk.c -SRCS+=ssh-ed25519-sk.c sk-usbhid.c +SRCS+=ssh-ed25519-sk.c sk-usbhid.c ssh-pkcs11-client.c +SRCS+=utf8.c ssherr-libcrypto.c + +SRCS+=digest-openssl.c ed25519-openssl.c +#SRCS+=digest-libc.c ed25519.c -SRCS+=digest-openssl.c -#SRCS+=digest-libc.c -SRCS+=utf8.c REGRESS_TARGETS=run-regress-${PROG} diff --git a/regress/unittests/sshkey/common.c b/regress/unittests/sshkey/common.c index f325c2a..fa68e6d 100644 --- a/regress/unittests/sshkey/common.c +++ b/regress/unittests/sshkey/common.c @@ -1,4 +1,4 @@ -/* $OpenBSD: common.c,v 1.6 2024/08/15 00:52:23 djm Exp $ */ +/* $OpenBSD: common.c,v 1.8 2025/06/16 08:49:27 dtucker Exp $ */ /* * Helpers for key API tests * @@ -11,9 +11,7 @@ #include #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include #include @@ -21,7 +19,6 @@ #ifdef WITH_OPENSSL #include #include -#include #include #ifdef OPENSSL_HAS_NISTP256 # include @@ -54,13 +51,13 @@ load_text_file(const char *name) { struct sshbuf *ret = load_file(name); const u_char *p; + size_t len; /* Trim whitespace at EOL */ - for (p = sshbuf_ptr(ret); sshbuf_len(ret) > 0;) { - if (p[sshbuf_len(ret) - 1] == '\r' || - p[sshbuf_len(ret) - 1] == '\t' || - p[sshbuf_len(ret) - 1] == ' ' || - p[sshbuf_len(ret) - 1] == '\n') + for (p = sshbuf_ptr(ret); (len = sshbuf_len(ret)) > 0;) { + len--; + if (p[len] == '\r' || p[len] == '\t' || + p[len] == ' ' || p[len] == '\n') ASSERT_INT_EQ(sshbuf_consume_end(ret, 1), 0); else break; @@ -126,38 +123,4 @@ rsa_q(struct sshkey *k) RSA_get0_factors(EVP_PKEY_get0_RSA(k->pkey), NULL, &q); return q; } - -const BIGNUM * -dsa_g(struct sshkey *k) -{ - const BIGNUM *g = NULL; - - ASSERT_PTR_NE(k, NULL); - ASSERT_PTR_NE(k->dsa, NULL); - DSA_get0_pqg(k->dsa, NULL, NULL, &g); - return g; -} - -const BIGNUM * -dsa_pub_key(struct sshkey *k) -{ - const BIGNUM *pub_key = NULL; - - ASSERT_PTR_NE(k, NULL); - ASSERT_PTR_NE(k->dsa, NULL); - DSA_get0_key(k->dsa, &pub_key, NULL); - return pub_key; -} - -const BIGNUM * -dsa_priv_key(struct sshkey *k) -{ - const BIGNUM *priv_key = NULL; - - ASSERT_PTR_NE(k, NULL); - ASSERT_PTR_NE(k->dsa, NULL); - DSA_get0_key(k->dsa, NULL, &priv_key); - return priv_key; -} #endif /* WITH_OPENSSL */ - diff --git a/regress/unittests/sshkey/common.h b/regress/unittests/sshkey/common.h index 7a514fd..6127116 100644 --- a/regress/unittests/sshkey/common.h +++ b/regress/unittests/sshkey/common.h @@ -1,4 +1,4 @@ -/* $OpenBSD: common.h,v 1.2 2018/09/13 09:03:20 djm Exp $ */ +/* $OpenBSD: common.h,v 1.3 2025/05/06 06:05:48 djm Exp $ */ /* * Helpers for key API tests * @@ -19,7 +19,4 @@ const BIGNUM *rsa_n(struct sshkey *k); const BIGNUM *rsa_e(struct sshkey *k); const BIGNUM *rsa_p(struct sshkey *k); const BIGNUM *rsa_q(struct sshkey *k); -const BIGNUM *dsa_g(struct sshkey *k); -const BIGNUM *dsa_pub_key(struct sshkey *k); -const BIGNUM *dsa_priv_key(struct sshkey *k); diff --git a/regress/unittests/sshkey/mktestdata.sh b/regress/unittests/sshkey/mktestdata.sh index fcd78e9..97e5d79 100755 --- a/regress/unittests/sshkey/mktestdata.sh +++ b/regress/unittests/sshkey/mktestdata.sh @@ -1,5 +1,5 @@ #!/bin/sh -# $OpenBSD: mktestdata.sh,v 1.11 2020/06/19 03:48:49 djm Exp $ +# $OpenBSD: mktestdata.sh,v 1.12 2025/05/06 06:05:48 djm Exp $ PW=mekmitasdigoat @@ -24,27 +24,6 @@ rsa_params() { done } -dsa_params() { - _in="$1" - _outbase="$2" - set -e - openssl dsa -noout -text -in $_in | \ - awk '/^priv:$/,/^pub:/' | \ - grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.priv - openssl dsa -noout -text -in $_in | \ - awk '/^pub:/,/^P:/' | #\ - grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.pub - openssl dsa -noout -text -in $_in | \ - awk '/^G:/,0' | \ - grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.g - for x in priv pub g ; do - echo "" >> ${_outbase}.$x - echo ============ ${_outbase}.$x - cat ${_outbase}.$x - echo ============ - done -} - ecdsa_params() { _in="$1" _outbase="$2" @@ -79,15 +58,14 @@ else exit 1 fi -rm -f rsa_1 dsa_1 ecdsa_1 ed25519_1 -rm -f rsa_2 dsa_2 ecdsa_2 ed25519_2 -rm -f rsa_n dsa_n ecdsa_n # new-format keys -rm -f rsa_1_pw dsa_1_pw ecdsa_1_pw ed25519_1_pw -rm -f rsa_n_pw dsa_n_pw ecdsa_n_pw +rm -f rsa_1 ecdsa_1 ed25519_1 +rm -f rsa_2 ecdsa_2 ed25519_2 +rm -f rsa_n ecdsa_n # new-format keys +rm -f rsa_1_pw ecdsa_1_pw ed25519_1_pw +rm -f rsa_n_pw ecdsa_n_pw rm -f pw *.pub *.bn.* *.param.* *.fp *.fp.bb ssh-keygen -t rsa -b 1024 -C "RSA test key #1" -N "" -f rsa_1 -m PEM -ssh-keygen -t dsa -b 1024 -C "DSA test key #1" -N "" -f dsa_1 -m PEM ssh-keygen -t ecdsa -b 256 -C "ECDSA test key #1" -N "" -f ecdsa_1 -m PEM ssh-keygen -t ed25519 -C "ED25519 test key #1" -N "" -f ed25519_1 ssh-keygen -w "$SK_DUMMY" -t ecdsa-sk -C "ECDSA-SK test key #1" \ @@ -97,7 +75,6 @@ ssh-keygen -w "$SK_DUMMY" -t ed25519-sk -C "ED25519-SK test key #1" \ ssh-keygen -t rsa -b 2048 -C "RSA test key #2" -N "" -f rsa_2 -m PEM -ssh-keygen -t dsa -b 1024 -C "DSA test key #2" -N "" -f dsa_2 -m PEM ssh-keygen -t ecdsa -b 521 -C "ECDSA test key #2" -N "" -f ecdsa_2 -m PEM ssh-keygen -t ed25519 -C "ED25519 test key #2" -N "" -f ed25519_2 ssh-keygen -w "$SK_DUMMY" -t ecdsa-sk -C "ECDSA-SK test key #2" \ @@ -106,37 +83,29 @@ ssh-keygen -w "$SK_DUMMY" -t ed25519-sk -C "ED25519-SK test key #2" \ -N "" -f ed25519_sk2 cp rsa_1 rsa_n -cp dsa_1 dsa_n cp ecdsa_1 ecdsa_n ssh-keygen -pf rsa_n -N "" -ssh-keygen -pf dsa_n -N "" ssh-keygen -pf ecdsa_n -N "" cp rsa_1 rsa_1_pw -cp dsa_1 dsa_1_pw cp ecdsa_1 ecdsa_1_pw cp ed25519_1 ed25519_1_pw cp ecdsa_sk1 ecdsa_sk1_pw cp ed25519_sk1 ed25519_sk1_pw cp rsa_1 rsa_n_pw -cp dsa_1 dsa_n_pw cp ecdsa_1 ecdsa_n_pw ssh-keygen -pf rsa_1_pw -m PEM -N "$PW" -ssh-keygen -pf dsa_1_pw -m PEM -N "$PW" ssh-keygen -pf ecdsa_1_pw -m PEM -N "$PW" ssh-keygen -pf ed25519_1_pw -N "$PW" ssh-keygen -pf ecdsa_sk1_pw -m PEM -N "$PW" ssh-keygen -pf ed25519_sk1_pw -N "$PW" ssh-keygen -pf rsa_n_pw -N "$PW" -ssh-keygen -pf dsa_n_pw -N "$PW" ssh-keygen -pf ecdsa_n_pw -N "$PW" rsa_params rsa_1 rsa_1.param rsa_params rsa_2 rsa_2.param -dsa_params dsa_1 dsa_1.param -dsa_params dsa_1 dsa_1.param ecdsa_params ecdsa_1 ecdsa_1.param ecdsa_params ecdsa_2 ecdsa_2.param # XXX ed25519, *sk params @@ -144,9 +113,6 @@ ecdsa_params ecdsa_2 ecdsa_2.param ssh-keygen -s rsa_2 -I hugo -n user1,user2 \ -Oforce-command=/bin/ls -Ono-port-forwarding -Osource-address=10.0.0.0/8 \ -V 19990101:20110101 -z 1 rsa_1.pub -ssh-keygen -s rsa_2 -I hugo -n user1,user2 \ - -Oforce-command=/bin/ls -Ono-port-forwarding -Osource-address=10.0.0.0/8 \ - -V 19990101:20110101 -z 2 dsa_1.pub ssh-keygen -s rsa_2 -I hugo -n user1,user2 \ -Oforce-command=/bin/ls -Ono-port-forwarding -Osource-address=10.0.0.0/8 \ -V 19990101:20110101 -z 3 ecdsa_1.pub @@ -175,8 +141,6 @@ ssh-keygen -s rsa_2 -I hugo -n user1,user2 -t rsa-sha2-512 \ ssh-keygen -s ed25519_1 -I julius -n host1,host2 -h \ -V 19990101:20110101 -z 5 rsa_1.pub -ssh-keygen -s ed25519_1 -I julius -n host1,host2 -h \ - -V 19990101:20110101 -z 6 dsa_1.pub ssh-keygen -s ecdsa_1 -I julius -n host1,host2 -h \ -V 19990101:20110101 -z 7 ecdsa_1.pub ssh-keygen -s ed25519_1 -I julius -n host1,host2 -h \ @@ -187,33 +151,28 @@ ssh-keygen -s ed25519_1 -I julius -n host1,host2 -h \ -V 19990101:20110101 -z 8 ed25519_sk1.pub ssh-keygen -lf rsa_1 | awk '{print $2}' > rsa_1.fp -ssh-keygen -lf dsa_1 | awk '{print $2}' > dsa_1.fp ssh-keygen -lf ecdsa_1 | awk '{print $2}' > ecdsa_1.fp ssh-keygen -lf ed25519_1 | awk '{print $2}' > ed25519_1.fp ssh-keygen -lf ecdsa_sk1 | awk '{print $2}' > ecdsa_sk1.fp ssh-keygen -lf ed25519_sk1 | awk '{print $2}' > ed25519_sk1.fp ssh-keygen -lf rsa_2 | awk '{print $2}' > rsa_2.fp -ssh-keygen -lf dsa_2 | awk '{print $2}' > dsa_2.fp ssh-keygen -lf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp ssh-keygen -lf ed25519_2 | awk '{print $2}' > ed25519_2.fp ssh-keygen -lf ecdsa_sk2 | awk '{print $2}' > ecdsa_sk2.fp ssh-keygen -lf ed25519_sk2 | awk '{print $2}' > ed25519_sk2.fp ssh-keygen -lf rsa_1-cert.pub | awk '{print $2}' > rsa_1-cert.fp -ssh-keygen -lf dsa_1-cert.pub | awk '{print $2}' > dsa_1-cert.fp ssh-keygen -lf ecdsa_1-cert.pub | awk '{print $2}' > ecdsa_1-cert.fp ssh-keygen -lf ed25519_1-cert.pub | awk '{print $2}' > ed25519_1-cert.fp ssh-keygen -lf ecdsa_sk1-cert.pub | awk '{print $2}' > ecdsa_sk1-cert.fp ssh-keygen -lf ed25519_sk1-cert.pub | awk '{print $2}' > ed25519_sk1-cert.fp ssh-keygen -Bf rsa_1 | awk '{print $2}' > rsa_1.fp.bb -ssh-keygen -Bf dsa_1 | awk '{print $2}' > dsa_1.fp.bb ssh-keygen -Bf ecdsa_1 | awk '{print $2}' > ecdsa_1.fp.bb ssh-keygen -Bf ed25519_1 | awk '{print $2}' > ed25519_1.fp.bb ssh-keygen -Bf ecdsa_sk1 | awk '{print $2}' > ecdsa_sk1.fp.bb ssh-keygen -Bf ed25519_sk1 | awk '{print $2}' > ed25519_sk1.fp.bb ssh-keygen -Bf rsa_2 | awk '{print $2}' > rsa_2.fp.bb -ssh-keygen -Bf dsa_2 | awk '{print $2}' > dsa_2.fp.bb ssh-keygen -Bf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp.bb ssh-keygen -Bf ed25519_2 | awk '{print $2}' > ed25519_2.fp.bb ssh-keygen -Bf ecdsa_sk2 | awk '{print $2}' > ecdsa_sk2.fp.bb diff --git a/regress/unittests/sshkey/test_file.c b/regress/unittests/sshkey/test_file.c index 3babe60..e412b75 100644 --- a/regress/unittests/sshkey/test_file.c +++ b/regress/unittests/sshkey/test_file.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_file.c,v 1.12 2024/08/15 00:52:23 djm Exp $ */ +/* $OpenBSD: test_file.c,v 1.13 2025/05/06 06:05:48 djm Exp $ */ /* * Regress test for sshkey.h key management API * @@ -11,9 +11,7 @@ #include #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include #include @@ -21,7 +19,6 @@ #ifdef WITH_OPENSSL #include #include -#include #include #ifdef OPENSSL_HAS_NISTP256 # include @@ -165,99 +162,6 @@ sshkey_file_tests(void) sshkey_free(k1); -#ifdef WITH_DSA - TEST_START("parse DSA from private"); - buf = load_file("dsa_1"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); - sshbuf_free(buf); - ASSERT_PTR_NE(k1, NULL); - a = load_bignum("dsa_1.param.g"); - b = load_bignum("dsa_1.param.priv"); - c = load_bignum("dsa_1.param.pub"); - ASSERT_BIGNUM_EQ(dsa_g(k1), a); - ASSERT_BIGNUM_EQ(dsa_priv_key(k1), b); - ASSERT_BIGNUM_EQ(dsa_pub_key(k1), c); - BN_free(a); - BN_free(b); - BN_free(c); - TEST_DONE(); - - TEST_START("parse DSA from private w/ passphrase"); - buf = load_file("dsa_1_pw"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, - (const char *)sshbuf_ptr(pw), &k2, NULL), 0); - sshbuf_free(buf); - ASSERT_PTR_NE(k2, NULL); - ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); - sshkey_free(k2); - TEST_DONE(); - - TEST_START("parse DSA from new-format"); - buf = load_file("dsa_n"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k2, NULL), 0); - sshbuf_free(buf); - ASSERT_PTR_NE(k2, NULL); - ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); - sshkey_free(k2); - TEST_DONE(); - - TEST_START("parse DSA from new-format w/ passphrase"); - buf = load_file("dsa_n_pw"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, - (const char *)sshbuf_ptr(pw), &k2, NULL), 0); - sshbuf_free(buf); - ASSERT_PTR_NE(k2, NULL); - ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); - sshkey_free(k2); - TEST_DONE(); - - TEST_START("load DSA from public"); - ASSERT_INT_EQ(sshkey_load_public(test_data_file("dsa_1.pub"), &k2, - NULL), 0); - ASSERT_PTR_NE(k2, NULL); - ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); - sshkey_free(k2); - TEST_DONE(); - - TEST_START("load DSA cert"); - ASSERT_INT_EQ(sshkey_load_cert(test_data_file("dsa_1"), &k2), 0); - ASSERT_PTR_NE(k2, NULL); - ASSERT_INT_EQ(k2->type, KEY_DSA_CERT); - ASSERT_INT_EQ(sshkey_equal(k1, k2), 0); - ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1); - TEST_DONE(); - - TEST_START("DSA key hex fingerprint"); - buf = load_text_file("dsa_1.fp"); - cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA256, SSH_FP_BASE64); - ASSERT_PTR_NE(cp, NULL); - ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); - sshbuf_free(buf); - free(cp); - TEST_DONE(); - - TEST_START("DSA cert hex fingerprint"); - buf = load_text_file("dsa_1-cert.fp"); - cp = sshkey_fingerprint(k2, SSH_DIGEST_SHA256, SSH_FP_BASE64); - ASSERT_PTR_NE(cp, NULL); - ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); - sshbuf_free(buf); - free(cp); - sshkey_free(k2); - TEST_DONE(); - - TEST_START("DSA key bubblebabble fingerprint"); - buf = load_text_file("dsa_1.fp.bb"); - cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); - ASSERT_PTR_NE(cp, NULL); - ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); - sshbuf_free(buf); - free(cp); - TEST_DONE(); - - sshkey_free(k1); -#endif - #ifdef OPENSSL_HAS_ECC TEST_START("parse ECDSA from private"); buf = load_file("ecdsa_1"); diff --git a/regress/unittests/sshkey/test_fuzz.c b/regress/unittests/sshkey/test_fuzz.c index 0aff7c9..d0f47d7 100644 --- a/regress/unittests/sshkey/test_fuzz.c +++ b/regress/unittests/sshkey/test_fuzz.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_fuzz.c,v 1.14 2024/01/11 01:45:58 djm Exp $ */ +/* $OpenBSD: test_fuzz.c,v 1.15 2025/05/06 06:05:48 djm Exp $ */ /* * Fuzz tests for key parsing * @@ -11,9 +11,7 @@ #include #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include #include @@ -21,7 +19,6 @@ #ifdef WITH_OPENSSL #include #include -#include #include #ifdef OPENSSL_HAS_NISTP256 # include @@ -160,52 +157,6 @@ sshkey_fuzz_tests(void) fuzz_cleanup(fuzz); TEST_DONE(); -#ifdef WITH_DSA - TEST_START("fuzz DSA private"); - buf = load_file("dsa_1"); - fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), - sshbuf_len(buf)); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); - sshkey_free(k1); - sshbuf_free(buf); - ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); - TEST_ONERROR(onerror, fuzz); - for(i = 0; !fuzz_done(fuzz); i++, fuzz_next(fuzz)) { - r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); - ASSERT_INT_EQ(r, 0); - if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0) - sshkey_free(k1); - sshbuf_reset(fuzzed); - if (test_is_fast() && i >= NUM_FAST_BASE64_TESTS) - break; - } - sshbuf_free(fuzzed); - fuzz_cleanup(fuzz); - TEST_DONE(); - - TEST_START("fuzz DSA new-format private"); - buf = load_file("dsa_n"); - fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), - sshbuf_len(buf)); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); - sshkey_free(k1); - sshbuf_free(buf); - ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); - TEST_ONERROR(onerror, fuzz); - for(i = 0; !fuzz_done(fuzz); i++, fuzz_next(fuzz)) { - r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); - ASSERT_INT_EQ(r, 0); - if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0) - sshkey_free(k1); - sshbuf_reset(fuzzed); - if (test_is_fast() && i >= NUM_FAST_BASE64_TESTS) - break; - } - sshbuf_free(fuzzed); - fuzz_cleanup(fuzz); - TEST_DONE(); -#endif - #ifdef OPENSSL_HAS_ECC TEST_START("fuzz ECDSA private"); buf = load_file("ecdsa_1"); @@ -290,22 +241,6 @@ sshkey_fuzz_tests(void) sshkey_free(k1); TEST_DONE(); -#ifdef WITH_DSA - TEST_START("fuzz DSA public"); - buf = load_file("dsa_1"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); - sshbuf_free(buf); - public_fuzz(k1); - sshkey_free(k1); - TEST_DONE(); - - TEST_START("fuzz DSA cert"); - ASSERT_INT_EQ(sshkey_load_cert(test_data_file("dsa_1"), &k1), 0); - public_fuzz(k1); - sshkey_free(k1); - TEST_DONE(); -#endif - #ifdef OPENSSL_HAS_ECC TEST_START("fuzz ECDSA public"); buf = load_file("ecdsa_1"); @@ -362,16 +297,6 @@ sshkey_fuzz_tests(void) sshkey_free(k1); TEST_DONE(); -#ifdef WITH_DSA - TEST_START("fuzz DSA sig"); - buf = load_file("dsa_1"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); - sshbuf_free(buf); - sig_fuzz(k1, NULL); - sshkey_free(k1); - TEST_DONE(); -#endif - #ifdef OPENSSL_HAS_ECC TEST_START("fuzz ECDSA sig"); buf = load_file("ecdsa_1"); diff --git a/regress/unittests/sshkey/test_sshkey.c b/regress/unittests/sshkey/test_sshkey.c index 5bf4b65..1701c87 100644 --- a/regress/unittests/sshkey/test_sshkey.c +++ b/regress/unittests/sshkey/test_sshkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_sshkey.c,v 1.25 2024/08/15 00:52:23 djm Exp $ */ +/* $OpenBSD: test_sshkey.c,v 1.33 2026/03/06 06:57:33 dtucker Exp $ */ /* * Regress test for sshkey.h key management API * @@ -9,16 +9,13 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include #ifdef WITH_OPENSSL #include #include -#include #if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) # include #endif @@ -36,6 +33,7 @@ #include "ssh2.h" void sshkey_tests(void); +void sshkey_benchmarks(void); static void put_opt(struct sshbuf *b, const char *name, const char *value) @@ -133,6 +131,55 @@ signature_test(struct sshkey *k, struct sshkey *bad, const char *sig_alg, free(sig); } +static void +signature_bench(const char *name, int ktype, int bits, const char *sig_alg, + const u_char *d, size_t l) +{ + struct sshkey *k; + size_t len; + u_char *sig; + char testname[256]; + + snprintf(testname, sizeof(testname), "sign %s", name); + TEST_START(testname); + ASSERT_INT_EQ(sshkey_generate(ktype, bits, &k), 0); + ASSERT_PTR_NE(k, NULL); + + BENCH_START(testname); + ASSERT_INT_EQ(sshkey_sign(k, &sig, &len, d, l, sig_alg, + NULL, NULL, 0), 0); + free(sig); + BENCH_FINISH("sign"); + + sshkey_free(k); + TEST_DONE(); +} + +static void +verify_bench(const char *name, int ktype, int bits, const char *sig_alg, + const u_char *d, size_t l) +{ + struct sshkey *k; + size_t len; + u_char *sig; + char testname[256]; + + snprintf(testname, sizeof(testname), "verify %s", name); + TEST_START(testname); + ASSERT_INT_EQ(sshkey_generate(ktype, bits, &k), 0); + ASSERT_PTR_NE(k, NULL); + + ASSERT_INT_EQ(sshkey_sign(k, &sig, &len, d, l, sig_alg, + NULL, NULL, 0), 0); + BENCH_START(testname); + ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0); + BENCH_FINISH("verify"); + + free(sig); + sshkey_free(k); + TEST_DONE(); +} + static void banana(u_char *s, size_t l) { @@ -165,6 +212,19 @@ signature_tests(struct sshkey *k, struct sshkey *bad, const char *sig_alg) } } +static void +signature_benchmark(const char *name, int ktype, int bits, + const char *sig_alg, int bench_verify) +{ + u_char buf[256]; + + banana(buf, sizeof(buf)); + if (bench_verify) + verify_bench(name, ktype, bits, sig_alg, buf, sizeof(buf)); + else + signature_bench(name, ktype, bits, sig_alg, buf, sizeof(buf)); +} + static struct sshkey * get_private(const char *n) { @@ -198,6 +258,7 @@ sshkey_tests(void) k1 = sshkey_new(KEY_UNSPEC); ASSERT_PTR_NE(k1, NULL); sshkey_free(k1); + k1 = NULL; TEST_DONE(); #ifdef WITH_OPENSSL @@ -206,16 +267,9 @@ sshkey_tests(void) ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1->pkey, NULL); sshkey_free(k1); + k1 = NULL; TEST_DONE(); -#ifdef WITH_DSA - TEST_START("new/free KEY_DSA"); - k1 = sshkey_new(KEY_DSA); - ASSERT_PTR_NE(k1, NULL); - ASSERT_PTR_NE(k1->dsa, NULL); - sshkey_free(k1); - TEST_DONE(); -#endif #ifdef OPENSSL_HAS_ECC TEST_START("new/free KEY_ECDSA"); @@ -223,6 +277,7 @@ sshkey_tests(void) ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_EQ(k1->pkey, NULL); /* Can't allocate without NID */ sshkey_free(k1); + k1 = NULL; TEST_DONE(); #endif @@ -233,6 +288,7 @@ sshkey_tests(void) ASSERT_PTR_EQ(k1->ed25519_sk, NULL); ASSERT_PTR_EQ(k1->ed25519_pk, NULL); sshkey_free(k1); + k1 = NULL; TEST_DONE(); TEST_START("generate KEY_RSA too small modulus"); @@ -247,14 +303,6 @@ sshkey_tests(void) ASSERT_PTR_EQ(k1, NULL); TEST_DONE(); -#ifdef WITH_DSA - TEST_START("generate KEY_DSA wrong bits"); - ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 2048, &k1), - SSH_ERR_KEY_LENGTH); - ASSERT_PTR_EQ(k1, NULL); - sshkey_free(k1); - TEST_DONE(); -#endif #ifdef OPENSSL_HAS_ECC TEST_START("generate KEY_ECDSA wrong bits"); @@ -262,6 +310,7 @@ sshkey_tests(void) SSH_ERR_KEY_LENGTH); ASSERT_PTR_EQ(k1, NULL); sshkey_free(k1); + k1 = NULL; TEST_DONE(); #endif @@ -277,15 +326,6 @@ sshkey_tests(void) ASSERT_INT_EQ(BN_num_bits(rsa_n(kr)), 1024); TEST_DONE(); -#ifdef WITH_DSA - TEST_START("generate KEY_DSA"); - ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &kd), 0); - ASSERT_PTR_NE(kd, NULL); - ASSERT_PTR_NE(kd->dsa, NULL); - ASSERT_PTR_NE(dsa_g(kd), NULL); - ASSERT_PTR_NE(dsa_priv_key(kd), NULL); - TEST_DONE(); -#endif #ifdef OPENSSL_HAS_ECC TEST_START("generate KEY_ECDSA"); @@ -323,24 +363,9 @@ sshkey_tests(void) TEST_START("equal KEY_RSA/demoted KEY_RSA"); ASSERT_INT_EQ(sshkey_equal(kr, k1), 1); sshkey_free(k1); + k1 = NULL; TEST_DONE(); -#ifdef WITH_DSA - TEST_START("demote KEY_DSA"); - ASSERT_INT_EQ(sshkey_from_private(kd, &k1), 0); - ASSERT_PTR_NE(k1, NULL); - ASSERT_PTR_NE(kd, k1); - ASSERT_INT_EQ(k1->type, KEY_DSA); - ASSERT_PTR_NE(k1->dsa, NULL); - ASSERT_PTR_NE(dsa_g(k1), NULL); - ASSERT_PTR_EQ(dsa_priv_key(k1), NULL); - TEST_DONE(); - - TEST_START("equal KEY_DSA/demoted KEY_DSA"); - ASSERT_INT_EQ(sshkey_equal(kd, k1), 1); - sshkey_free(k1); - TEST_DONE(); -#endif #ifdef OPENSSL_HAS_ECC TEST_START("demote KEY_ECDSA"); @@ -359,6 +384,7 @@ sshkey_tests(void) TEST_START("equal KEY_ECDSA/demoted KEY_ECDSA"); ASSERT_INT_EQ(sshkey_equal(ke, k1), 1); sshkey_free(k1); + k1 = NULL; TEST_DONE(); #endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ @@ -375,6 +401,7 @@ sshkey_tests(void) TEST_START("equal KEY_ED25519/demoted KEY_ED25519"); ASSERT_INT_EQ(sshkey_equal(kf, k1), 1); sshkey_free(k1); + k1 = NULL; TEST_DONE(); #ifdef WITH_OPENSSL @@ -394,15 +421,18 @@ sshkey_tests(void) ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &k1), 0); ASSERT_INT_EQ(sshkey_equal(kr, k1), 0); sshkey_free(k1); + k1 = NULL; #ifdef OPENSSL_HAS_ECC ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &k1), 0); ASSERT_INT_EQ(sshkey_equal(ke, k1), 0); sshkey_free(k1); + k1 = NULL; #endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &k1), 0); ASSERT_INT_EQ(sshkey_equal(kf, k1), 0); sshkey_free(k1); + k1 = NULL; TEST_DONE(); #ifdef WITH_OPENSSL @@ -436,7 +466,7 @@ sshkey_tests(void) ASSERT_PTR_NE(k1->cert->principals[3], NULL); k1->cert->nprincipals = 4; k1->cert->valid_after = 0; - k1->cert->valid_before = (u_int64_t)-1; + k1->cert->valid_before = (uint64_t)-1; sshbuf_free(k1->cert->critical); k1->cert->critical = sshbuf_new(); ASSERT_PTR_NE(k1->cert->critical, NULL); @@ -457,6 +487,7 @@ sshkey_tests(void) sshkey_free(k1); sshkey_free(k2); sshkey_free(k3); + k1 = k2 = k3 = NULL; sshbuf_reset(b); TEST_DONE(); @@ -468,6 +499,7 @@ sshkey_tests(void) signature_tests(k1, k2, "ssh-rsa"); sshkey_free(k1); sshkey_free(k2); + k1 = k2 = NULL; TEST_DONE(); TEST_START("sign and verify RSA-SHA256"); @@ -477,6 +509,7 @@ sshkey_tests(void) signature_tests(k1, k2, "rsa-sha2-256"); sshkey_free(k1); sshkey_free(k2); + k1 = k2 = NULL; TEST_DONE(); TEST_START("sign and verify RSA-SHA512"); @@ -486,18 +519,9 @@ sshkey_tests(void) signature_tests(k1, k2, "rsa-sha2-512"); sshkey_free(k1); sshkey_free(k2); + k1 = k2 = NULL; TEST_DONE(); -#ifdef WITH_DSA - TEST_START("sign and verify DSA"); - k1 = get_private("dsa_1"); - ASSERT_INT_EQ(sshkey_load_public(test_data_file("dsa_2.pub"), &k2, - NULL), 0); - signature_tests(k1, k2, NULL); - sshkey_free(k1); - sshkey_free(k2); - TEST_DONE(); -#endif #ifdef OPENSSL_HAS_ECC TEST_START("sign and verify ECDSA"); @@ -507,6 +531,7 @@ sshkey_tests(void) signature_tests(k1, k2, NULL); sshkey_free(k1); sshkey_free(k2); + k1 = k2 = NULL; TEST_DONE(); #endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ @@ -518,6 +543,7 @@ sshkey_tests(void) signature_tests(k1, k2, NULL); sshkey_free(k1); sshkey_free(k2); + k1 = k2 = NULL; TEST_DONE(); #ifdef WITH_OPENSSL @@ -533,7 +559,96 @@ sshkey_tests(void) sshkey_free(k1); sshkey_free(k2); sshkey_free(k3); + k1 = k2 = k3 = NULL; sshbuf_free(b); TEST_DONE(); #endif /* WITH_OPENSSL */ } + +void +sshkey_benchmarks(void) +{ + struct sshkey *k = NULL; + +#ifdef WITH_OPENSSL + BENCH_START("generate RSA-1024"); + TEST_START("generate KEY_RSA"); + ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &k), 0); + ASSERT_PTR_NE(k, NULL); + sshkey_free(k); + k = NULL; + TEST_DONE(); + BENCH_FINISH("keys"); + + BENCH_START("generate RSA-2048"); + TEST_START("generate KEY_RSA"); + ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 2048, &k), 0); + ASSERT_PTR_NE(k, NULL); + sshkey_free(k); + k = NULL; + TEST_DONE(); + BENCH_FINISH("keys"); + + BENCH_START("generate ECDSA-256"); + TEST_START("generate KEY_ECDSA"); + ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &k), 0); + ASSERT_PTR_NE(k, NULL); + sshkey_free(k); + k = NULL; + TEST_DONE(); + BENCH_FINISH("keys"); + + BENCH_START("generate ECDSA-384"); + TEST_START("generate KEY_ECDSA"); + ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 384, &k), 0); + ASSERT_PTR_NE(k, NULL); + sshkey_free(k); + k = NULL; + TEST_DONE(); + BENCH_FINISH("keys"); + + BENCH_START("generate ECDSA-521"); + TEST_START("generate KEY_ECDSA"); + ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 521, &k), 0); + ASSERT_PTR_NE(k, NULL); + sshkey_free(k); + k = NULL; + TEST_DONE(); + BENCH_FINISH("keys"); +#endif /* WITH_OPENSSL */ + + BENCH_START("generate ED25519"); + TEST_START("generate KEY_ED25519"); + ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &k), 0); + ASSERT_PTR_NE(k, NULL); + sshkey_free(k); + k = NULL; + TEST_DONE(); + BENCH_FINISH("keys"); + +#ifdef WITH_OPENSSL + /* sign */ + signature_benchmark("RSA-1024/SHA1", KEY_RSA, 1024, "ssh-rsa", 0); + signature_benchmark("RSA-1024/SHA256", KEY_RSA, 1024, "rsa-sha2-256", 0); + signature_benchmark("RSA-1024/SHA512", KEY_RSA, 1024, "rsa-sha2-512", 0); + signature_benchmark("RSA-2048/SHA1", KEY_RSA, 2048, "ssh-rsa", 0); + signature_benchmark("RSA-2048/SHA256", KEY_RSA, 2048, "rsa-sha2-256", 0); + signature_benchmark("RSA-2048/SHA512", KEY_RSA, 2048, "rsa-sha2-512", 0); + signature_benchmark("ECDSA-256", KEY_ECDSA, 256, NULL, 0); + signature_benchmark("ECDSA-384", KEY_ECDSA, 384, NULL, 0); + signature_benchmark("ECDSA-521", KEY_ECDSA, 521, NULL, 0); + signature_benchmark("ED25519", KEY_ED25519, 0, NULL, 0); + + /* verify */ + signature_benchmark("RSA-1024/SHA1", KEY_RSA, 1024, "ssh-rsa", 1); + signature_benchmark("RSA-1024/SHA256", KEY_RSA, 1024, "rsa-sha2-256", 1); + signature_benchmark("RSA-1024/SHA512", KEY_RSA, 1024, "rsa-sha2-512", 1); + signature_benchmark("RSA-2048/SHA1", KEY_RSA, 2048, "ssh-rsa", 1); + signature_benchmark("RSA-2048/SHA256", KEY_RSA, 2048, "rsa-sha2-256", 1); + signature_benchmark("RSA-2048/SHA512", KEY_RSA, 2048, "rsa-sha2-512", 1); + signature_benchmark("ECDSA-256", KEY_ECDSA, 256, NULL, 1); + signature_benchmark("ECDSA-384", KEY_ECDSA, 384, NULL, 1); + signature_benchmark("ECDSA-521", KEY_ECDSA, 521, NULL, 1); +#endif /* WITH_OPENSSL */ + signature_benchmark("ED25519", KEY_ED25519, 0, NULL, 1); +} diff --git a/regress/unittests/sshkey/testdata/dsa_1 b/regress/unittests/sshkey/testdata/dsa_1 deleted file mode 100644 index d3f2482..0000000 --- a/regress/unittests/sshkey/testdata/dsa_1 +++ /dev/null @@ -1,12 +0,0 @@ ------BEGIN DSA PRIVATE KEY----- -MIIBvAIBAAKBgQD6kutNFRsHTwEAv6d39Lhsqy1apdHBZ9c2HfyRr7WmypyGIy2m -Ka43vzXI8CNwmRSYs+A6d0vJC7Pl+f9QzJ/04NWOA+MiwfurwrR3CRe61QRYb8Py -mcHOxueHs95IcjrbIPNn86cjnPP5qvv/guUzCjuww4zBdJOXpligrGt2XwIVAKMD -/50qQy7j8JaMk+1+Xtg1pK01AoGBAO7l9QVVbSSoy5lq6cOtvpf8UlwOa6+zBwbl -o4gmFd1RwX1yWkA8kQ7RrhCSg8Hc6mIGnKRgKRli/3LgbSfZ0obFJehkRtEWtN4P -h8fVUeS74iQbIwFQeKlYHIlNTRoGtAbdi3nHdV+BBkEQc1V3rjqYqhjOoz/yNsgz -LND26HrdAoGBAOdXpyfmobEBaOqZAuvgj1P0uhjG2P31Ufurv22FWPBU3A9qrkxb -OXwE0LwvjCvrsQV/lrYhJz/tiys40VeahulWZE5SAHMXGIf95LiLSgaXMjko7joo -t+LK84ltLymwZ4QMnYjnZSSclf1UuyQMcUtb34+I0u9Ycnyhp2mSFsQtAhRYIbQ5 -KfXsZuBPuWe5FJz3ldaEgw== ------END DSA PRIVATE KEY----- diff --git a/regress/unittests/sshkey/testdata/dsa_1-cert.fp b/regress/unittests/sshkey/testdata/dsa_1-cert.fp deleted file mode 100644 index 75ff0e9..0000000 --- a/regress/unittests/sshkey/testdata/dsa_1-cert.fp +++ /dev/null @@ -1 +0,0 @@ -SHA256:kOLgXSoAT8O5T6r36n5NJUYigbux1d7gdH/rmWiJm6s diff --git a/regress/unittests/sshkey/testdata/dsa_1-cert.pub b/regress/unittests/sshkey/testdata/dsa_1-cert.pub deleted file mode 100644 index e768db1..0000000 --- a/regress/unittests/sshkey/testdata/dsa_1-cert.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-dss-cert-v01@openssh.com AAAAHHNzaC1kc3MtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgdTlbNU9Hn9Qng3FHxwH971bxCIoq1ern/QWFFDWXgmYAAACBAPqS600VGwdPAQC/p3f0uGyrLVql0cFn1zYd/JGvtabKnIYjLaYprje/NcjwI3CZFJiz4Dp3S8kLs+X5/1DMn/Tg1Y4D4yLB+6vCtHcJF7rVBFhvw/KZwc7G54ez3khyOtsg82fzpyOc8/mq+/+C5TMKO7DDjMF0k5emWKCsa3ZfAAAAFQCjA/+dKkMu4/CWjJPtfl7YNaStNQAAAIEA7uX1BVVtJKjLmWrpw62+l/xSXA5rr7MHBuWjiCYV3VHBfXJaQDyRDtGuEJKDwdzqYgacpGApGWL/cuBtJ9nShsUl6GRG0Ra03g+Hx9VR5LviJBsjAVB4qVgciU1NGga0Bt2Lecd1X4EGQRBzVXeuOpiqGM6jP/I2yDMs0Pboet0AAACBAOdXpyfmobEBaOqZAuvgj1P0uhjG2P31Ufurv22FWPBU3A9qrkxbOXwE0LwvjCvrsQV/lrYhJz/tiys40VeahulWZE5SAHMXGIf95LiLSgaXMjko7joot+LK84ltLymwZ4QMnYjnZSSclf1UuyQMcUtb34+I0u9Ycnyhp2mSFsQtAAAAAAAAAAYAAAACAAAABmp1bGl1cwAAABIAAAAFaG9zdDEAAAAFaG9zdDIAAAAANowB8AAAAABNHmBwAAAAAAAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACBThupGO0X+FLQhbz8CoKPwc7V3JNsQuGtlsgN+F7SMGQAAAFMAAAALc3NoLWVkMjU1MTkAAABAh/z1LIdNL1b66tQ8t9DY9BTB3BQKpTKmc7ezyFKLwl96yaIniZwD9Ticdbe/8i/Li3uCFE3EAt8NAIv9zff8Bg== DSA test key #1 diff --git a/regress/unittests/sshkey/testdata/dsa_1.fp b/regress/unittests/sshkey/testdata/dsa_1.fp deleted file mode 100644 index 75ff0e9..0000000 --- a/regress/unittests/sshkey/testdata/dsa_1.fp +++ /dev/null @@ -1 +0,0 @@ -SHA256:kOLgXSoAT8O5T6r36n5NJUYigbux1d7gdH/rmWiJm6s diff --git a/regress/unittests/sshkey/testdata/dsa_1.fp.bb b/regress/unittests/sshkey/testdata/dsa_1.fp.bb deleted file mode 100644 index ba37776..0000000 --- a/regress/unittests/sshkey/testdata/dsa_1.fp.bb +++ /dev/null @@ -1 +0,0 @@ -xetag-todiz-mifah-torec-mynyv-cyvit-gopon-pygag-rupic-cenav-bexax diff --git a/regress/unittests/sshkey/testdata/dsa_1.param.g b/regress/unittests/sshkey/testdata/dsa_1.param.g deleted file mode 100644 index e51c3f9..0000000 --- a/regress/unittests/sshkey/testdata/dsa_1.param.g +++ /dev/null @@ -1 +0,0 @@ -00eee5f505556d24a8cb996ae9c3adbe97fc525c0e6bafb30706e5a3882615dd51c17d725a403c910ed1ae109283c1dcea62069ca460291962ff72e06d27d9d286c525e86446d116b4de0f87c7d551e4bbe2241b23015078a9581c894d4d1a06b406dd8b79c7755f81064110735577ae3a98aa18cea33ff236c8332cd0f6e87add diff --git a/regress/unittests/sshkey/testdata/dsa_1.param.priv b/regress/unittests/sshkey/testdata/dsa_1.param.priv deleted file mode 100644 index 4f74331..0000000 --- a/regress/unittests/sshkey/testdata/dsa_1.param.priv +++ /dev/null @@ -1 +0,0 @@ -5821b43929f5ec66e04fb967b9149cf795d68483 diff --git a/regress/unittests/sshkey/testdata/dsa_1.param.pub b/regress/unittests/sshkey/testdata/dsa_1.param.pub deleted file mode 100644 index ba0313b..0000000 --- a/regress/unittests/sshkey/testdata/dsa_1.param.pub +++ /dev/null @@ -1 +0,0 @@ -00e757a727e6a1b10168ea9902ebe08f53f4ba18c6d8fdf551fbabbf6d8558f054dc0f6aae4c5b397c04d0bc2f8c2bebb1057f96b621273fed8b2b38d1579a86e956644e520073171887fde4b88b4a0697323928ee3a28b7e2caf3896d2f29b067840c9d88e765249c95fd54bb240c714b5bdf8f88d2ef58727ca1a7699216c42d diff --git a/regress/unittests/sshkey/testdata/dsa_1.pub b/regress/unittests/sshkey/testdata/dsa_1.pub deleted file mode 100644 index 41cae2f..0000000 --- a/regress/unittests/sshkey/testdata/dsa_1.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-dss AAAAB3NzaC1kc3MAAACBAPqS600VGwdPAQC/p3f0uGyrLVql0cFn1zYd/JGvtabKnIYjLaYprje/NcjwI3CZFJiz4Dp3S8kLs+X5/1DMn/Tg1Y4D4yLB+6vCtHcJF7rVBFhvw/KZwc7G54ez3khyOtsg82fzpyOc8/mq+/+C5TMKO7DDjMF0k5emWKCsa3ZfAAAAFQCjA/+dKkMu4/CWjJPtfl7YNaStNQAAAIEA7uX1BVVtJKjLmWrpw62+l/xSXA5rr7MHBuWjiCYV3VHBfXJaQDyRDtGuEJKDwdzqYgacpGApGWL/cuBtJ9nShsUl6GRG0Ra03g+Hx9VR5LviJBsjAVB4qVgciU1NGga0Bt2Lecd1X4EGQRBzVXeuOpiqGM6jP/I2yDMs0Pboet0AAACBAOdXpyfmobEBaOqZAuvgj1P0uhjG2P31Ufurv22FWPBU3A9qrkxbOXwE0LwvjCvrsQV/lrYhJz/tiys40VeahulWZE5SAHMXGIf95LiLSgaXMjko7joot+LK84ltLymwZ4QMnYjnZSSclf1UuyQMcUtb34+I0u9Ycnyhp2mSFsQt DSA test key #1 diff --git a/regress/unittests/sshkey/testdata/dsa_1_pw b/regress/unittests/sshkey/testdata/dsa_1_pw deleted file mode 100644 index 24c7303..0000000 --- a/regress/unittests/sshkey/testdata/dsa_1_pw +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN DSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: AES-128-CBC,BC8386C373B22EB7F00ADC821D5D8BE9 - -+HDV2DQ09sxrIAeXTz9r3YFuPRa2hk1+NGcr3ETkXbC6KiZ14wpTnGTloKwaQjIW -eXTa9mpCOWAoohgvsVb+hOuOlP7AfeHu1IXV4EAS+GDpkiV5UxlCXXwqlD75Buu4 -wwDd/p4SWzILH3WGjDk5JIXoxWNY13LHwC7Q6gtGJx4AicUG7YBRTXMIBDa/Kh77 -6o2rFETKmp4VHBvHbakmiETfptdM8bbWxKWeY2vakThyESgeofsLoTOQCIwlEfJC -s2D/KYL65C8VbHYgIoSLTQnooO45DDyxIuhCqP+H23mhv9vB1Od3nc2atgHj/XFs -dcOPFkF/msDRYqxY3V0AS6+jpKwFodZ7g/hyGcyPxOkzlJVuKoKuH6P5PyQ69Gx0 -iqri0xEPyABr7kGlXNrjjctojX+B4WwSnjg/2euXXWFXCRalIdA7ErATTiQbGOx7 -Vd6Gn8PZbSy1MkqEDrZRip0pfAFJYI/8GXPC75BpnRsrVlfhtrngbW+kBP35LzaN -l2K+RQ3gSB3iFoqNb1Kuu6T5MZlyVl5H2dVlJSeb1euQ2OycXdDoFTyJ4AiyWS7w -Vlh8zeJnso5QRDjMwx99pZilbbuFGSLsahiGEveFc6o= ------END DSA PRIVATE KEY----- diff --git a/regress/unittests/sshkey/testdata/dsa_2 b/regress/unittests/sshkey/testdata/dsa_2 deleted file mode 100644 index 3cc9631..0000000 --- a/regress/unittests/sshkey/testdata/dsa_2 +++ /dev/null @@ -1,12 +0,0 @@ ------BEGIN DSA PRIVATE KEY----- -MIIBvQIBAAKBgQCbyPXNdHeLsjpobPVCMkfagBkt15Zsltqf/PGNP1y1cuz7rsTX -ZekQwUkSTNm5coqXe+ZOw2O4tjobJDd60I1/VPgaB0NYlQR9Hn87M284WD4f6VY+ -aunHmP134a8ybG5G4NqVNF3ihvxAR2pVITqb7kE46r2uYZNcNlHI8voRCwIVAMcP -bwqFNsQbH5pJyZW30wj4KVZ3AoGBAIK98BVeKQVf8qDFqx9ovMuNgVSxpd+N0Yta -5ZEy1OI2ziu5RhjueIM2K7Gq2Mnp38ob1AM53BUxqlcBJaHEDa6rj6yvuMgW9oCJ -dImBM8sIFxfBbXNbpJiMaDwa6WyT84OkpDE6uuAepTMnWOUWkUVkAiyokHDUGXkG -GyoQblbXAoGBAIsf7TaZ804sUWwRV0wI8DYx+hxD5QdrfYPYMtL2fHn3lICimGt0 -FTtUZ25jKg0E0DMBPdET6ZEHB3ZZkR8hFoUzZhdnyJMu3UjVtgaV88Ue3PrXxchk -0W2jHPaAgQU3JIWzo8HFIFqvC/HEL+EyW3rBTY2uXM3XGI+YcWSA4ZrZAhUAsY2f -bDFNzgZ4DaZ9wLRzTgOswPU= ------END DSA PRIVATE KEY----- diff --git a/regress/unittests/sshkey/testdata/dsa_2.fp b/regress/unittests/sshkey/testdata/dsa_2.fp deleted file mode 100644 index 51fbeb4..0000000 --- a/regress/unittests/sshkey/testdata/dsa_2.fp +++ /dev/null @@ -1 +0,0 @@ -SHA256:ecwhWcXgpdBxZ2e+OjpRRY7dqXHHCD62BGtoVQQBwCk diff --git a/regress/unittests/sshkey/testdata/dsa_2.fp.bb b/regress/unittests/sshkey/testdata/dsa_2.fp.bb deleted file mode 100644 index 4d908ee..0000000 --- a/regress/unittests/sshkey/testdata/dsa_2.fp.bb +++ /dev/null @@ -1 +0,0 @@ -xeser-megad-pocan-rozit-belup-tapoh-fapif-kyvit-vonav-cehab-naxax diff --git a/regress/unittests/sshkey/testdata/dsa_2.pub b/regress/unittests/sshkey/testdata/dsa_2.pub deleted file mode 100644 index 77bb555..0000000 --- a/regress/unittests/sshkey/testdata/dsa_2.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-dss AAAAB3NzaC1kc3MAAACBAJvI9c10d4uyOmhs9UIyR9qAGS3XlmyW2p/88Y0/XLVy7PuuxNdl6RDBSRJM2blyipd75k7DY7i2OhskN3rQjX9U+BoHQ1iVBH0efzszbzhYPh/pVj5q6ceY/XfhrzJsbkbg2pU0XeKG/EBHalUhOpvuQTjqva5hk1w2Ucjy+hELAAAAFQDHD28KhTbEGx+aScmVt9MI+ClWdwAAAIEAgr3wFV4pBV/yoMWrH2i8y42BVLGl343Ri1rlkTLU4jbOK7lGGO54gzYrsarYyenfyhvUAzncFTGqVwElocQNrquPrK+4yBb2gIl0iYEzywgXF8Ftc1ukmIxoPBrpbJPzg6SkMTq64B6lMydY5RaRRWQCLKiQcNQZeQYbKhBuVtcAAACBAIsf7TaZ804sUWwRV0wI8DYx+hxD5QdrfYPYMtL2fHn3lICimGt0FTtUZ25jKg0E0DMBPdET6ZEHB3ZZkR8hFoUzZhdnyJMu3UjVtgaV88Ue3PrXxchk0W2jHPaAgQU3JIWzo8HFIFqvC/HEL+EyW3rBTY2uXM3XGI+YcWSA4ZrZ DSA test key #2 diff --git a/regress/unittests/sshkey/testdata/dsa_n b/regress/unittests/sshkey/testdata/dsa_n deleted file mode 100644 index 657624e..0000000 --- a/regress/unittests/sshkey/testdata/dsa_n +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN OPENSSH PRIVATE KEY----- -b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABswAAAAdzc2gtZH -NzAAAAgQD6kutNFRsHTwEAv6d39Lhsqy1apdHBZ9c2HfyRr7WmypyGIy2mKa43vzXI8CNw -mRSYs+A6d0vJC7Pl+f9QzJ/04NWOA+MiwfurwrR3CRe61QRYb8PymcHOxueHs95IcjrbIP -Nn86cjnPP5qvv/guUzCjuww4zBdJOXpligrGt2XwAAABUAowP/nSpDLuPwloyT7X5e2DWk -rTUAAACBAO7l9QVVbSSoy5lq6cOtvpf8UlwOa6+zBwblo4gmFd1RwX1yWkA8kQ7RrhCSg8 -Hc6mIGnKRgKRli/3LgbSfZ0obFJehkRtEWtN4Ph8fVUeS74iQbIwFQeKlYHIlNTRoGtAbd -i3nHdV+BBkEQc1V3rjqYqhjOoz/yNsgzLND26HrdAAAAgQDnV6cn5qGxAWjqmQLr4I9T9L -oYxtj99VH7q79thVjwVNwPaq5MWzl8BNC8L4wr67EFf5a2ISc/7YsrONFXmobpVmROUgBz -FxiH/eS4i0oGlzI5KO46KLfiyvOJbS8psGeEDJ2I52UknJX9VLskDHFLW9+PiNLvWHJ8oa -dpkhbELQAAAdhWTOFbVkzhWwAAAAdzc2gtZHNzAAAAgQD6kutNFRsHTwEAv6d39Lhsqy1a -pdHBZ9c2HfyRr7WmypyGIy2mKa43vzXI8CNwmRSYs+A6d0vJC7Pl+f9QzJ/04NWOA+Miwf -urwrR3CRe61QRYb8PymcHOxueHs95IcjrbIPNn86cjnPP5qvv/guUzCjuww4zBdJOXplig -rGt2XwAAABUAowP/nSpDLuPwloyT7X5e2DWkrTUAAACBAO7l9QVVbSSoy5lq6cOtvpf8Ul -wOa6+zBwblo4gmFd1RwX1yWkA8kQ7RrhCSg8Hc6mIGnKRgKRli/3LgbSfZ0obFJehkRtEW -tN4Ph8fVUeS74iQbIwFQeKlYHIlNTRoGtAbdi3nHdV+BBkEQc1V3rjqYqhjOoz/yNsgzLN -D26HrdAAAAgQDnV6cn5qGxAWjqmQLr4I9T9LoYxtj99VH7q79thVjwVNwPaq5MWzl8BNC8 -L4wr67EFf5a2ISc/7YsrONFXmobpVmROUgBzFxiH/eS4i0oGlzI5KO46KLfiyvOJbS8psG -eEDJ2I52UknJX9VLskDHFLW9+PiNLvWHJ8oadpkhbELQAAABRYIbQ5KfXsZuBPuWe5FJz3 -ldaEgwAAAAAB ------END OPENSSH PRIVATE KEY----- diff --git a/regress/unittests/sshkey/testdata/dsa_n_pw b/regress/unittests/sshkey/testdata/dsa_n_pw deleted file mode 100644 index 24ac299..0000000 --- a/regress/unittests/sshkey/testdata/dsa_n_pw +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN OPENSSH PRIVATE KEY----- -b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABCVs+LsMJ -wnB5zM9U9pTXrGAAAAEAAAAAEAAAGzAAAAB3NzaC1kc3MAAACBAPqS600VGwdPAQC/p3f0 -uGyrLVql0cFn1zYd/JGvtabKnIYjLaYprje/NcjwI3CZFJiz4Dp3S8kLs+X5/1DMn/Tg1Y -4D4yLB+6vCtHcJF7rVBFhvw/KZwc7G54ez3khyOtsg82fzpyOc8/mq+/+C5TMKO7DDjMF0 -k5emWKCsa3ZfAAAAFQCjA/+dKkMu4/CWjJPtfl7YNaStNQAAAIEA7uX1BVVtJKjLmWrpw6 -2+l/xSXA5rr7MHBuWjiCYV3VHBfXJaQDyRDtGuEJKDwdzqYgacpGApGWL/cuBtJ9nShsUl -6GRG0Ra03g+Hx9VR5LviJBsjAVB4qVgciU1NGga0Bt2Lecd1X4EGQRBzVXeuOpiqGM6jP/ -I2yDMs0Pboet0AAACBAOdXpyfmobEBaOqZAuvgj1P0uhjG2P31Ufurv22FWPBU3A9qrkxb -OXwE0LwvjCvrsQV/lrYhJz/tiys40VeahulWZE5SAHMXGIf95LiLSgaXMjko7joot+LK84 -ltLymwZ4QMnYjnZSSclf1UuyQMcUtb34+I0u9Ycnyhp2mSFsQtAAAB4HiOcRW4w+sIqBL0 -TPVbf0glN1hUi0rcE63Pqxmvxb8LkldC4IxAUagPrjhNAEW2AY42+CvPrtGB1z7gDADAIW -xZX6wKwIcXP0Qh+xHE12F4u6mwfasssnAp4t1Ki8uCjMjnimgb3KdWpp0kiUV0oR062TXV -PAdfrWjaq4fw0KOqbHIAG/v36AqzuqjSTfDbqvLZM3y0gp2Q1RxaQVJA5ZIKKyqRyFX7sr -BaEIyCgeE3hM0EB7BycY1oIcS/eNxrACBWVJCENl5N7LtEYXNX7TANFniztfXzwaqGTT6A -fCfbW4gz1UKldLUBzbIrPwMWlirAstbHvOf/2Iay2pNAs/SHhI0aF2jsGfvv5/D6N+r9dG -B2SgDKBg7pywMH1DTvg6YT3P4GjCx0GUHqRCFLvD1rDdk4KSjvaRMpVq1PJ0/Wv6UGtsMS -TR0PaEHDRNZqAX4YxqujnWrGKuRJhuz0eUvp7fZvbWHtiAMKV7368kkeUmkOHanb+TS+zs -KINX8ev8zJZ6WVr8Vl+IQavpv0i2bXwS6QqbEuifpv/+uBb7pqRiU4u8en0eMdX1bZoTPM -R6xHCnGD/Jpb3zS91Ya57T6CiXZ12KCaL6nWGnCkZVpzkfJ2HjFklWSWBQ6uyaosDQ== ------END OPENSSH PRIVATE KEY----- diff --git a/regress/unittests/sshkey/tests.c b/regress/unittests/sshkey/tests.c index 78aa922..426543b 100644 --- a/regress/unittests/sshkey/tests.c +++ b/regress/unittests/sshkey/tests.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tests.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */ +/* $OpenBSD: tests.c,v 1.2 2025/04/15 04:00:42 djm Exp $ */ /* * Regress test for sshbuf.h buffer API * @@ -7,11 +7,14 @@ #include "includes.h" +#include + #include "../test_helper/test_helper.h" void sshkey_tests(void); void sshkey_file_tests(void); void sshkey_fuzz_tests(void); +void sshkey_benchmarks(void); void tests(void) @@ -20,3 +23,10 @@ tests(void) sshkey_file_tests(); sshkey_fuzz_tests(); } + +void +benchmarks(void) +{ + printf("\n"); + sshkey_benchmarks(); +} diff --git a/regress/unittests/sshsig/Makefile b/regress/unittests/sshsig/Makefile index bc3c6c7..54abd84 100644 --- a/regress/unittests/sshsig/Makefile +++ b/regress/unittests/sshsig/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.3 2023/01/15 23:35:10 djm Exp $ +# $OpenBSD: Makefile,v 1.7 2026/02/06 23:39:14 dtucker Exp $ PROG=test_sshsig SRCS=tests.c @@ -6,15 +6,14 @@ SRCS=tests.c # From usr.bin/ssh SRCS+=sshbuf-getput-basic.c sshbuf-getput-crypto.c sshbuf-misc.c sshbuf.c SRCS+=sshbuf-io.c atomicio.c sshkey.c authfile.c cipher.c log.c ssh-rsa.c -SRCS+=ssh-dss.c ssh-ecdsa.c ssh-ed25519.c mac.c umac.c umac128.c hmac.c misc.c +SRCS+=ssh-ecdsa.c ssh-ed25519.c mac.c umac.c umac128.c hmac.c misc.c SRCS+=ssherr.c uidswap.c cleanup.c xmalloc.c match.c krl.c fatal.c SRCS+=addr.c addrmatch.c bitmap.c sshsig.c -SRCS+=ed25519.c hash.c SRCS+=cipher-chachapoly.c chacha.c poly1305.c ssh-ecdsa-sk.c ssh-sk.c -SRCS+=ssh-ed25519-sk.c sk-usbhid.c +SRCS+=ssh-ed25519-sk.c sk-usbhid.c ssh-pkcs11-client.c ssherr-libcrypto.c -SRCS+=digest-openssl.c -#SRCS+=digest-libc.c +SRCS+=digest-openssl.c ed25519-openssl.c +#SRCS+=digest-libc.c ed25519.c SRCS+=utf8.c REGRESS_TARGETS=run-regress-${PROG} diff --git a/regress/unittests/sshsig/mktestdata.sh b/regress/unittests/sshsig/mktestdata.sh index d2300f9..b7c60cc 100755 --- a/regress/unittests/sshsig/mktestdata.sh +++ b/regress/unittests/sshsig/mktestdata.sh @@ -1,5 +1,5 @@ #!/bin/sh -# $OpenBSD: mktestdata.sh,v 1.1 2020/06/19 04:32:09 djm Exp $ +# $OpenBSD: mktestdata.sh,v 1.2 2025/05/06 06:05:48 djm Exp $ NAMESPACE=unittest @@ -17,14 +17,13 @@ else fi rm -f signed-data namespace -rm -f rsa dsa ecdsa ed25519 ecdsa_sk ed25519_sk -rm -f rsa.sig dsa.sig ecdsa.sig ed25519.sig ecdsa_sk.sig ed25519_sk.sig +rm -f rsa ecdsa ed25519 ecdsa_sk ed25519_sk +rm -f rsa.sig ecdsa.sig ed25519.sig ecdsa_sk.sig ed25519_sk.sig printf "This is a test, this is only a test" > signed-data printf "$NAMESPACE" > namespace ssh-keygen -t rsa -C "RSA test" -N "" -f rsa -m PEM -ssh-keygen -t dsa -C "DSA test" -N "" -f dsa -m PEM ssh-keygen -t ecdsa -C "ECDSA test" -N "" -f ecdsa -m PEM ssh-keygen -t ed25519 -C "ED25519 test key" -N "" -f ed25519 ssh-keygen -w "$SK_DUMMY" -t ecdsa-sk -C "ECDSA-SK test key" \ @@ -33,7 +32,6 @@ ssh-keygen -w "$SK_DUMMY" -t ed25519-sk -C "ED25519-SK test key" \ -N "" -f ed25519_sk ssh-keygen -Y sign -f rsa -n $NAMESPACE - < signed-data > rsa.sig -ssh-keygen -Y sign -f dsa -n $NAMESPACE - < signed-data > dsa.sig ssh-keygen -Y sign -f ecdsa -n $NAMESPACE - < signed-data > ecdsa.sig ssh-keygen -Y sign -f ed25519 -n $NAMESPACE - < signed-data > ed25519.sig ssh-keygen -w "$SK_DUMMY" \ diff --git a/regress/unittests/sshsig/testdata/dsa b/regress/unittests/sshsig/testdata/dsa deleted file mode 100644 index 7c0063e..0000000 --- a/regress/unittests/sshsig/testdata/dsa +++ /dev/null @@ -1,12 +0,0 @@ ------BEGIN DSA PRIVATE KEY----- -MIIBuwIBAAKBgQCXpndQdz2mQVnk+lYOF3nxDT+h6SiJmUvBFhnFWBv8tG4pTOkb -EwGufLEzGpzjTj+3bjVau7LFt37AFrqs4Num272BWNsYNIjOlGPgq7Xjv32FN00x -JYh1DoRs1cGGnvohlsWEamGGhTHD1a9ipctPEBV+NrxtZMrl+pO/ZZg8vQIVAKJB -P3iNYSpSuW74+q4WxLCuK8O3AoGAQldE+BIuxlvoG1IFiWesx0CU+H2KO0SEZc9A -SX/qjOabh0Fb78ofTlEf9gWHFfat8SvSJQIOPMVlb76Lio8AAMT8Eaa/qQKKYmQL -dNq4MLhhjxx5KLGt6J2JyFPExCv+qnHYHD59ngtLwKyqGjpSC8LPLktdXn8W/Aad -Ly1K7+MCgYBsMHBczhSeUh8w7i20CVg4OlNTmfJRVU2tO6OpMxZ/quitRm3hLKSN -u4xRkvHJwi4LhQtv1SXvLI5gs5P3gCG8tsIAiyCqLinHha63iBdJpqhnV/x/j7dB -yJr3xJbnmLdWLkkCtNk1Ir1/CuEz+ufAyLGdKWksEAu1UUlb501BkwIVAILIa3Rg -0h7J9lQpHJphvF3K0M1T ------END DSA PRIVATE KEY----- diff --git a/regress/unittests/sshsig/testdata/dsa.pub b/regress/unittests/sshsig/testdata/dsa.pub deleted file mode 100644 index e77aa7e..0000000 --- a/regress/unittests/sshsig/testdata/dsa.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-dss AAAAB3NzaC1kc3MAAACBAJemd1B3PaZBWeT6Vg4XefENP6HpKImZS8EWGcVYG/y0bilM6RsTAa58sTManONOP7duNVq7ssW3fsAWuqzg26bbvYFY2xg0iM6UY+CrteO/fYU3TTEliHUOhGzVwYae+iGWxYRqYYaFMcPVr2Kly08QFX42vG1kyuX6k79lmDy9AAAAFQCiQT94jWEqUrlu+PquFsSwrivDtwAAAIBCV0T4Ei7GW+gbUgWJZ6zHQJT4fYo7RIRlz0BJf+qM5puHQVvvyh9OUR/2BYcV9q3xK9IlAg48xWVvvouKjwAAxPwRpr+pAopiZAt02rgwuGGPHHkosa3onYnIU8TEK/6qcdgcPn2eC0vArKoaOlILws8uS11efxb8Bp0vLUrv4wAAAIBsMHBczhSeUh8w7i20CVg4OlNTmfJRVU2tO6OpMxZ/quitRm3hLKSNu4xRkvHJwi4LhQtv1SXvLI5gs5P3gCG8tsIAiyCqLinHha63iBdJpqhnV/x/j7dByJr3xJbnmLdWLkkCtNk1Ir1/CuEz+ufAyLGdKWksEAu1UUlb501Bkw== DSA test diff --git a/regress/unittests/sshsig/testdata/dsa.sig b/regress/unittests/sshsig/testdata/dsa.sig deleted file mode 100644 index 0b14ad6..0000000 --- a/regress/unittests/sshsig/testdata/dsa.sig +++ /dev/null @@ -1,13 +0,0 @@ ------BEGIN SSH SIGNATURE----- -U1NIU0lHAAAAAQAAAbEAAAAHc3NoLWRzcwAAAIEAl6Z3UHc9pkFZ5PpWDhd58Q0/oekoiZ -lLwRYZxVgb/LRuKUzpGxMBrnyxMxqc404/t241Wruyxbd+wBa6rODbptu9gVjbGDSIzpRj -4Ku14799hTdNMSWIdQ6EbNXBhp76IZbFhGphhoUxw9WvYqXLTxAVfja8bWTK5fqTv2WYPL -0AAAAVAKJBP3iNYSpSuW74+q4WxLCuK8O3AAAAgEJXRPgSLsZb6BtSBYlnrMdAlPh9ijtE -hGXPQEl/6ozmm4dBW+/KH05RH/YFhxX2rfEr0iUCDjzFZW++i4qPAADE/BGmv6kCimJkC3 -TauDC4YY8ceSixreidichTxMQr/qpx2Bw+fZ4LS8Csqho6UgvCzy5LXV5/FvwGnS8tSu/j -AAAAgGwwcFzOFJ5SHzDuLbQJWDg6U1OZ8lFVTa07o6kzFn+q6K1GbeEspI27jFGS8cnCLg -uFC2/VJe8sjmCzk/eAIby2wgCLIKouKceFrreIF0mmqGdX/H+Pt0HImvfElueYt1YuSQK0 -2TUivX8K4TP658DIsZ0paSwQC7VRSVvnTUGTAAAACHVuaXR0ZXN0AAAAAAAAAAZzaGE1MT -IAAAA3AAAAB3NzaC1kc3MAAAAodi5lr0pqBpO76OY4N1CtfR85BCgZ95qfVjP/e9lToj0q -lwjSJJXUjw== ------END SSH SIGNATURE----- diff --git a/regress/unittests/sshsig/tests.c b/regress/unittests/sshsig/tests.c index 80966bd..670d067 100644 --- a/regress/unittests/sshsig/tests.c +++ b/regress/unittests/sshsig/tests.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tests.c,v 1.4 2024/01/11 01:45:59 djm Exp $ */ +/* $OpenBSD: tests.c,v 1.6 2025/05/06 06:05:48 djm Exp $ */ /* * Regress test for sshbuf.h buffer API * @@ -11,9 +11,7 @@ #include #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include #include @@ -103,11 +101,6 @@ tests(void) check_sig("rsa.pub", "rsa.sig", msg, namespace); TEST_DONE(); -#ifdef WITH_DSA - TEST_START("check DSA signature"); - check_sig("dsa.pub", "dsa.sig", msg, namespace); - TEST_DONE(); -#endif #ifdef OPENSSL_HAS_ECC TEST_START("check ECDSA signature"); @@ -142,3 +135,9 @@ tests(void) sshbuf_free(msg); free(namespace); } + +void +benchmarks(void) +{ + printf("no benchmarks\n"); +} diff --git a/regress/unittests/test_helper/fuzz.c b/regress/unittests/test_helper/fuzz.c index 9995b26..c2711c7 100644 --- a/regress/unittests/test_helper/fuzz.c +++ b/regress/unittests/test_helper/fuzz.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fuzz.c,v 1.8 2015/03/03 20:42:49 djm Exp $ */ +/* $OpenBSD: fuzz.c,v 1.9 2025/06/13 07:23:07 dtucker Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -25,9 +25,7 @@ #include #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include #include @@ -150,7 +148,6 @@ fuzz_fmt(struct fuzz *fuzz, char *s, size_t n) return 0; default: return -1; - abort(); } } diff --git a/regress/unittests/test_helper/test_helper.c b/regress/unittests/test_helper/test_helper.c index e23128a..525a82b 100644 --- a/regress/unittests/test_helper/test_helper.c +++ b/regress/unittests/test_helper/test_helper.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_helper.c,v 1.13 2021/12/14 21:25:27 deraadt Exp $ */ +/* $OpenBSD: test_helper.c,v 1.16 2026/03/06 06:57:33 dtucker Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -21,18 +21,20 @@ #include #include - -#include +#include + +#include #include +#include +#include +#include +#include +#include #include -#ifdef HAVE_STDINT_H -# include -#endif #include #include -#include +#include #include -#include #ifdef WITH_OPENSSL #include @@ -43,12 +45,21 @@ # include #endif -#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) - #include "entropy.h" #include "test_helper.h" #include "atomicio.h" +#include "match.h" +#include "misc.h" +#include "xmalloc.h" +#define BENCH_FAST_DEADLINE 1 +#define BENCH_NORMAL_DEADLINE 10 +#define BENCH_SLOW_DEADLINE 60 +#define BENCH_SAMPLES_ALLOC 8192 +#define BENCH_COLUMN_WIDTH 40 + +#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) + #define TEST_CHECK_INT(r, pred) do { \ switch (pred) { \ case TEST_EQ: \ @@ -123,6 +134,15 @@ static const char *data_dir = NULL; static char subtest_info[512]; static int fast = 0; static int slow = 0; +static int benchmark_detail_statistics = 0; + +static int benchmark = 0; +static const char *bench_name = NULL; +static char *benchmark_pattern = NULL; +static struct timespec bench_start_time, bench_finish_time; +static struct timespec *bench_samples; +static int bench_skip, bench_nruns, bench_nalloc; +double bench_accum_secs; int main(int argc, char **argv) @@ -147,8 +167,17 @@ main(int argc, char **argv) } } - while ((ch = getopt(argc, argv, "Ffvqd:")) != -1) { + while ((ch = getopt(argc, argv, "O:bBFfvqd:")) != -1) { switch (ch) { + case 'b': + benchmark = 1; + break; + case 'B': + benchmark = benchmark_detail_statistics = 1; + break; + case 'O': + benchmark_pattern = xstrdup(optarg); + break; case 'F': slow = 1; break; @@ -168,7 +197,8 @@ main(int argc, char **argv) break; default: fprintf(stderr, "Unrecognised command line option\n"); - fprintf(stderr, "Usage: %s [-v]\n", __progname); + fprintf(stderr, "Usage: %s [-vqfFbB] [-d data_dir] " + "[-O pattern]\n", __progname); exit(1); } } @@ -178,9 +208,12 @@ main(int argc, char **argv) if (verbose_mode) printf("\n"); - tests(); + if (benchmark) + benchmarks(); + else + tests(); - if (!quiet_mode) + if (!quiet_mode && !benchmark) printf(" %u tests ok\n", test_number); return 0; } @@ -274,7 +307,7 @@ test_done(void) active_test_name = NULL; if (verbose_mode) printf("OK\n"); - else if (!quiet_mode) { + else if (!quiet_mode && !benchmark) { printf("."); fflush(stdout); } @@ -290,6 +323,12 @@ test_subtest_info(const char *fmt, ...) va_end(ap); } +int +test_is_benchmark(void) +{ + return benchmark; +} + void ssl_err_check(const char *file, int line) { @@ -382,23 +421,6 @@ assert_string(const char *file, int line, const char *a1, const char *a2, test_die(); } -static char * -tohex(const void *_s, size_t l) -{ - u_int8_t *s = (u_int8_t *)_s; - size_t i, j; - const char *hex = "0123456789abcdef"; - char *r = malloc((l * 2) + 1); - - assert(r != NULL); - for (i = j = 0; i < l; i++) { - r[j++] = hex[(s[i] >> 4) & 0xf]; - r[j++] = hex[s[i] & 0xf]; - } - r[j] = '\0'; - return r; -} - void assert_mem(const char *file, int line, const char *a1, const char *a2, const void *aa1, const void *aa2, size_t l, enum test_predicate pred) @@ -426,7 +448,7 @@ assert_mem(const char *file, int line, const char *a1, const char *a2, } static int -memvalcmp(const u_int8_t *s, u_char v, size_t l, size_t *where) +memvalcmp(const uint8_t *s, u_char v, size_t l, size_t *where) { size_t i; @@ -538,7 +560,7 @@ assert_char(const char *file, int line, const char *a1, const char *a2, void assert_u8(const char *file, int line, const char *a1, const char *a2, - u_int8_t aa1, u_int8_t aa2, enum test_predicate pred) + uint8_t aa1, uint8_t aa2, enum test_predicate pred) { TEST_CHECK(aa1, aa2, pred); test_header(file, line, a1, a2, "U8", pred); @@ -549,7 +571,7 @@ assert_u8(const char *file, int line, const char *a1, const char *a2, void assert_u16(const char *file, int line, const char *a1, const char *a2, - u_int16_t aa1, u_int16_t aa2, enum test_predicate pred) + uint16_t aa1, uint16_t aa2, enum test_predicate pred) { TEST_CHECK(aa1, aa2, pred); test_header(file, line, a1, a2, "U16", pred); @@ -560,7 +582,7 @@ assert_u16(const char *file, int line, const char *a1, const char *a2, void assert_u32(const char *file, int line, const char *a1, const char *a2, - u_int32_t aa1, u_int32_t aa2, enum test_predicate pred) + uint32_t aa1, uint32_t aa2, enum test_predicate pred) { TEST_CHECK(aa1, aa2, pred); test_header(file, line, a1, a2, "U32", pred); @@ -571,7 +593,7 @@ assert_u32(const char *file, int line, const char *a1, const char *a2, void assert_u64(const char *file, int line, const char *a1, const char *a2, - u_int64_t aa1, u_int64_t aa2, enum test_predicate pred) + uint64_t aa1, uint64_t aa2, enum test_predicate pred) { TEST_CHECK(aa1, aa2, pred); test_header(file, line, a1, a2, "U64", pred); @@ -582,6 +604,47 @@ assert_u64(const char *file, int line, const char *a1, const char *a2, test_die(); } +void +assert_double(const char *file, int line, const char *a1, const char *a2, + double aa1, double aa2, enum test_predicate pred) +{ + const double epsilon = 0.000000001; + + switch (pred) { + case TEST_EQ: + if (fabs(aa1 - aa2) < epsilon) + return; + break; + case TEST_NE: + if (fabs(aa1 - aa2) >= epsilon) + return; + break; + case TEST_LT: + if (aa1 < aa2) + return; + break; + case TEST_LE: + if (aa1 <= aa2) + return; + break; + case TEST_GT: + if (aa1 > aa2) + return; + break; + case TEST_GE: + if (aa1 >= aa2) + return; + break; + default: + abort(); + } + + test_header(file, line, a1, a2, "DOUBLE", pred); + fprintf(stderr, "%12s = %f\n", a1, aa1); + fprintf(stderr, "%12s = %f\n", a2, aa2); + test_die(); +} + void assert_ptr(const char *file, int line, const char *a1, const char *a2, const void *aa1, const void *aa2, enum test_predicate pred) @@ -593,3 +656,131 @@ assert_ptr(const char *file, int line, const char *a1, const char *a2, test_die(); } +static double +tstod(const struct timespec *ts) +{ + return (double)ts->tv_sec + ((double)ts->tv_nsec / 1000000000.0); +} + +void +bench_start(const char *file, int line, const char *name) +{ + char *cp; + + if (bench_name != NULL) { + fprintf(stderr, "\n%s:%d internal error: BENCH_START() called " + "while previous benchmark \"%s\" incomplete", + file, line, bench_name); + abort(); + } + cp = xstrdup(name); + lowercase(cp); + bench_skip = benchmark_pattern != NULL && + match_pattern_list(cp, benchmark_pattern, 1) != 1; + free(cp); + + bench_name = name; + bench_nruns = 0; + if (bench_skip) + return; + free(bench_samples); + bench_nalloc = BENCH_SAMPLES_ALLOC; + bench_samples = xcalloc(sizeof(*bench_samples), bench_nalloc); + bench_accum_secs = 0; +} + +int +bench_done(void) +{ + return bench_skip || bench_accum_secs >= (fast ? BENCH_FAST_DEADLINE : + (slow ? BENCH_SLOW_DEADLINE : BENCH_NORMAL_DEADLINE)); +} + +void +bench_case_start(const char *file, int line) +{ + clock_gettime(CLOCK_REALTIME, &bench_start_time); +} + +void +bench_case_finish(const char *file, int line) +{ + struct timespec ts; + + clock_gettime(CLOCK_REALTIME, &bench_finish_time); + timespecsub(&bench_finish_time, &bench_start_time, &ts); + if (bench_nruns >= bench_nalloc) { + if (bench_nalloc >= INT_MAX / 2) { + fprintf(stderr, "\n%s:%d benchmark %s too many samples", + __FILE__, __LINE__, bench_name); + abort(); + } + bench_samples = xrecallocarray(bench_samples, bench_nalloc, + bench_nalloc * 2, sizeof(*bench_samples)); + bench_nalloc *= 2; + } + bench_samples[bench_nruns++] = ts; + bench_accum_secs += tstod(&ts); +} + +static int +tscmp(const void *aa, const void *bb) +{ + const struct timespec *a = (const struct timespec *)aa; + const struct timespec *b = (const struct timespec *)bb; + + if (timespeccmp(a, b, ==)) + return 0; + return timespeccmp(a, b, <) ? -1 : 1; +} + +void +bench_finish(const char *file, int line, const char *unit) +{ + double std_dev = 0, mean_spr, mean_rps, med_spr, med_rps; + int i; + + if (bench_skip) + goto done; + + if (bench_nruns < 1) { + fprintf(stderr, "\n%s:%d benchmark %s never ran", file, line, + bench_name); + abort(); + } + /* median */ + qsort(bench_samples, bench_nruns, sizeof(*bench_samples), tscmp); + i = bench_nruns / 2; + med_spr = tstod(&bench_samples[i]); + if (bench_nruns > 1 && bench_nruns & 1) + med_spr = (med_spr + tstod(&bench_samples[i - 1])) / 2.0; + med_rps = (med_spr == 0.0) ? INFINITY : 1.0/med_spr; + /* mean */ + mean_spr = bench_accum_secs / (double)bench_nruns; + mean_rps = (mean_spr == 0.0) ? INFINITY : 1.0/mean_spr; + /* std. dev */ + std_dev = 0; + for (i = 0; i < bench_nruns; i++) { + std_dev = tstod(&bench_samples[i]) - mean_spr; + std_dev *= std_dev; + } + std_dev /= (double)bench_nruns; + std_dev = sqrt(std_dev); + if (benchmark_detail_statistics) { + printf("%s: %d runs in %0.3fs, %0.03f/%0.03f ms/%s " + "(mean/median), std.dev %0.03f ms, " + "%0.2f/%0.2f %s/s (mean/median)\n", + bench_name, bench_nruns, bench_accum_secs, + mean_spr * 1000, med_spr * 1000, unit, std_dev * 1000, + mean_rps, med_rps, unit); + } else { + printf("%-*s %0.2f %s/s\n", BENCH_COLUMN_WIDTH, + bench_name, med_rps, unit); + } + done: + bench_name = NULL; + bench_nruns = 0; + free(bench_samples); + bench_samples = NULL; + bench_skip = 0; +} diff --git a/regress/unittests/test_helper/test_helper.h b/regress/unittests/test_helper/test_helper.h index 6630220..91fdca4 100644 --- a/regress/unittests/test_helper/test_helper.h +++ b/regress/unittests/test_helper/test_helper.h @@ -1,4 +1,4 @@ -/* $OpenBSD: test_helper.h,v 1.9 2018/10/17 23:28:05 djm Exp $ */ +/* $OpenBSD: test_helper.h,v 1.12 2026/03/06 06:57:33 dtucker Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -23,9 +23,7 @@ #include "includes.h" #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #ifdef WITH_OPENSSL #include @@ -39,6 +37,7 @@ typedef void (test_onerror_func_t)(void *); /* Supplied by test suite */ void tests(void); +void benchmarks(void); const char *test_data_file(const char *name); void test_start(const char *n); @@ -49,6 +48,7 @@ int test_is_verbose(void); int test_is_quiet(void); int test_is_fast(void); int test_is_slow(void); +int test_is_benchmark(void); void test_subtest_info(const char *fmt, ...) __attribute__((format(printf, 1, 2))); void ssl_err_check(const char *file, int line); @@ -89,16 +89,19 @@ void assert_ptr(const char *file, int line, const void *aa1, const void *aa2, enum test_predicate pred); void assert_u8(const char *file, int line, const char *a1, const char *a2, - u_int8_t aa1, u_int8_t aa2, enum test_predicate pred); + uint8_t aa1, uint8_t aa2, enum test_predicate pred); void assert_u16(const char *file, int line, const char *a1, const char *a2, - u_int16_t aa1, u_int16_t aa2, enum test_predicate pred); + uint16_t aa1, uint16_t aa2, enum test_predicate pred); void assert_u32(const char *file, int line, const char *a1, const char *a2, - u_int32_t aa1, u_int32_t aa2, enum test_predicate pred); + uint32_t aa1, uint32_t aa2, enum test_predicate pred); void assert_u64(const char *file, int line, const char *a1, const char *a2, - u_int64_t aa1, u_int64_t aa2, enum test_predicate pred); + uint64_t aa1, uint64_t aa2, enum test_predicate pred); +void assert_double(const char *file, int line, + const char *a1, const char *a2, + double aa1, double aa2, enum test_predicate pred); #define TEST_START(n) test_start(n) #define TEST_DONE() test_done() @@ -285,6 +288,39 @@ void assert_u64(const char *file, int line, #define ASSERT_U64_GE(a1, a2) \ assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) +#define ASSERT_DOUBLE_EQ(a1, a2) \ + assert_double(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ) +#define ASSERT_DOUBLE_NE(a1, a2) \ + assert_double(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE) +#define ASSERT_DOUBLE_LT(a1, a2) \ + assert_double(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT) +#define ASSERT_DOUBLE_LE(a1, a2) \ + assert_double(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE) +#define ASSERT_DOUBLE_GT(a1, a2) \ + assert_double(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT) +#define ASSERT_DOUBLE_GE(a1, a2) \ + assert_double(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) + +/* Benchmarking support */ +#define BENCH_START(name) \ + do { \ + bench_start(__FILE__, __LINE__, name); \ + while (!bench_done()) { \ + bench_case_start(__FILE__, __LINE__); \ + do { +#define BENCH_FINISH(unit) \ + } while (0); \ + bench_case_finish(__FILE__, __LINE__); \ + } \ + bench_finish(__FILE__, __LINE__, unit); \ + } while (0) + +void bench_start(const char *file, int line, const char *name); +void bench_case_start(const char *file, int line); +void bench_case_finish(const char *file, int line); +void bench_finish(const char *file, int line, const char *unit); +int bench_done(void); + /* Fuzzing support */ struct fuzz; diff --git a/regress/unittests/utf8/Makefile b/regress/unittests/utf8/Makefile index f8eec04..a549573 100644 --- a/regress/unittests/utf8/Makefile +++ b/regress/unittests/utf8/Makefile @@ -1,14 +1,16 @@ -# $OpenBSD: Makefile,v 1.5 2017/12/21 00:41:22 djm Exp $ +# $OpenBSD: Makefile,v 1.7 2026/02/06 23:39:14 dtucker Exp $ PROG=test_utf8 SRCS=tests.c # From usr.bin/ssh -SRCS+=utf8.c atomicio.c +SRCS+=utf8.c atomicio.c misc.c xmalloc.c match.c ssherr.c cleanup.c fatal.c +SRCS+=sshbuf.c sshbuf-getput-basic.c sshbuf-misc.c addr.c addrmatch.c log.c +SRCS+=ssherr-libcrypto.c REGRESS_TARGETS=run-regress-${PROG} run-regress-${PROG}: ${PROG} - env ${TEST_ENV} ./${PROG} + env ${TEST_ENV} ./${PROG} ${UNITTEST_ARGS} .include diff --git a/regress/unittests/utf8/tests.c b/regress/unittests/utf8/tests.c index 8cf524d..3fb6341 100644 --- a/regress/unittests/utf8/tests.c +++ b/regress/unittests/utf8/tests.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tests.c,v 1.4 2017/02/19 00:11:29 djm Exp $ */ +/* $OpenBSD: tests.c,v 1.5 2025/04/15 04:00:42 djm Exp $ */ /* * Regress test for the utf8.h *mprintf() API * @@ -102,3 +102,9 @@ tests(void) one(0, "double_fit", "a\343\201\201", 7, 5, -1, "a\\343"); one(0, "double_spc", "a\343\201\201", 13, 13, 13, "a\\343\\201\\201"); } + +void +benchmarks(void) +{ + printf("no benchmarks\n"); +} diff --git a/rijndael.c b/rijndael.c index 40ab7b1..805687b 100644 --- a/rijndael.c +++ b/rijndael.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rijndael.c,v 1.20 2015/03/16 11:09:52 djm Exp $ */ +/* $OpenBSD: rijndael.c,v 1.21 2026/02/11 17:05:32 dtucker Exp $ */ /** * rijndael-alg-fst.c diff --git a/sandbox-capsicum.c b/sandbox-capsicum.c index 1104525..ec07a7d 100644 --- a/sandbox-capsicum.c +++ b/sandbox-capsicum.c @@ -45,8 +45,8 @@ */ struct ssh_sandbox { - struct monitor *monitor; - pid_t child_pid; + int m_recvfd; + int m_log_sendfd; }; struct ssh_sandbox * @@ -54,15 +54,10 @@ ssh_sandbox_init(struct monitor *monitor) { struct ssh_sandbox *box; - /* - * Strictly, we don't need to maintain any state here but we need - * to return non-NULL to satisfy the API. - */ - debug3("%s: preparing capsicum sandbox", __func__); + debug3_f("preparing capsicum sandbox"); box = xcalloc(1, sizeof(*box)); - box->monitor = monitor; - box->child_pid = 0; - + box->m_recvfd = monitor->m_recvfd; + box->m_log_sendfd = monitor->m_log_sendfd; return box; } @@ -100,29 +95,16 @@ ssh_sandbox_child(struct ssh_sandbox *box) fatal("can't limit stderr: %m"); cap_rights_init(&rights, CAP_READ, CAP_WRITE); - if (cap_rights_limit(box->monitor->m_recvfd, &rights) < 0 && + if (cap_rights_limit(box->m_recvfd, &rights) < 0 && errno != ENOSYS) - fatal("%s: failed to limit the network socket", __func__); + fatal_f("failed to limit the network socket"); cap_rights_init(&rights, CAP_WRITE); - if (cap_rights_limit(box->monitor->m_log_sendfd, &rights) < 0 && + if (cap_rights_limit(box->m_log_sendfd, &rights) < 0 && errno != ENOSYS) - fatal("%s: failed to limit the logging socket", __func__); + fatal_f("failed to limit the logging socket"); if (cap_enter() < 0 && errno != ENOSYS) - fatal("%s: failed to enter capability mode", __func__); - -} + fatal_f("failed to enter capability mode"); -void -ssh_sandbox_parent_finish(struct ssh_sandbox *box) -{ - free(box); - debug3("%s: finished", __func__); -} - -void -ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) -{ - box->child_pid = child_pid; } #endif /* SANDBOX_CAPSICUM */ diff --git a/sandbox-darwin.c b/sandbox-darwin.c index 59b4d28..98a339e 100644 --- a/sandbox-darwin.c +++ b/sandbox-darwin.c @@ -37,7 +37,7 @@ /* Darwin/OS X sandbox */ struct ssh_sandbox { - pid_t child_pid; + int junk; }; struct ssh_sandbox * @@ -49,10 +49,8 @@ ssh_sandbox_init(struct monitor *monitor) * Strictly, we don't need to maintain any state here but we need * to return non-NULL to satisfy the API. */ - debug3("%s: preparing Darwin sandbox", __func__); + debug3_f("preparing Darwin sandbox"); box = xcalloc(1, sizeof(*box)); - box->child_pid = 0; - return box; } @@ -62,10 +60,10 @@ ssh_sandbox_child(struct ssh_sandbox *box) char *errmsg; struct rlimit rl_zero; - debug3("%s: starting Darwin sandbox", __func__); + debug3_f("starting Darwin sandbox"); if (sandbox_init(kSBXProfilePureComputation, SANDBOX_NAMED, &errmsg) == -1) - fatal("%s: sandbox_init: %s", __func__, errmsg); + fatal_f("sandbox_init: %s", errmsg); /* * The kSBXProfilePureComputation still allows sockets, so @@ -83,17 +81,4 @@ ssh_sandbox_child(struct ssh_sandbox *box) __func__, strerror(errno)); } -void -ssh_sandbox_parent_finish(struct ssh_sandbox *box) -{ - free(box); - debug3("%s: finished", __func__); -} - -void -ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) -{ - box->child_pid = child_pid; -} - #endif /* SANDBOX_DARWIN */ diff --git a/sandbox-null.c b/sandbox-null.c index d4cb918..6055eb8 100644 --- a/sandbox-null.c +++ b/sandbox-null.c @@ -57,16 +57,4 @@ ssh_sandbox_child(struct ssh_sandbox *box) /* Nothing to do here */ } -void -ssh_sandbox_parent_finish(struct ssh_sandbox *box) -{ - free(box); -} - -void -ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) -{ - /* Nothing to do here */ -} - #endif /* SANDBOX_NULL */ diff --git a/sandbox-pledge.c b/sandbox-pledge.c deleted file mode 100644 index 302f1cf..0000000 --- a/sandbox-pledge.c +++ /dev/null @@ -1,77 +0,0 @@ -/* $OpenBSD: sandbox-pledge.c,v 1.2 2020/10/18 11:32:01 djm Exp $ */ -/* - * Copyright (c) 2015 Theo de Raadt - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, 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. - */ - -#include "includes.h" - -#ifdef SANDBOX_PLEDGE - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "log.h" -#include "ssh-sandbox.h" -#include "xmalloc.h" - -struct ssh_sandbox { - pid_t child_pid; -}; - -struct ssh_sandbox * -ssh_sandbox_init(struct monitor *m) -{ - struct ssh_sandbox *box; - - debug3_f("preparing pledge sandbox"); - box = xcalloc(1, sizeof(*box)); - box->child_pid = 0; - - return box; -} - -void -ssh_sandbox_child(struct ssh_sandbox *box) -{ - if (pledge("stdio", NULL) == -1) - fatal_f("pledge()"); -} - -void -ssh_sandbox_parent_finish(struct ssh_sandbox *box) -{ - free(box); - debug3_f("finished"); -} - -void -ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) -{ - box->child_pid = child_pid; - /* Nothing to do here */ -} - -#endif /* SANDBOX_PLEDGE */ diff --git a/sandbox-rlimit.c b/sandbox-rlimit.c index 26c61d2..6bb4e56 100644 --- a/sandbox-rlimit.c +++ b/sandbox-rlimit.c @@ -37,7 +37,7 @@ /* Minimal sandbox that sets zero nfiles, nprocs and filesize rlimits */ struct ssh_sandbox { - pid_t child_pid; + int junk; }; struct ssh_sandbox * @@ -51,8 +51,6 @@ ssh_sandbox_init(struct monitor *monitor) */ debug3_f("preparing rlimit sandbox"); box = xcalloc(1, sizeof(*box)); - box->child_pid = 0; - return box; } @@ -80,17 +78,4 @@ ssh_sandbox_child(struct ssh_sandbox *box) #endif } -void -ssh_sandbox_parent_finish(struct ssh_sandbox *box) -{ - free(box); - debug3_f("finished"); -} - -void -ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) -{ - box->child_pid = child_pid; -} - #endif /* SANDBOX_RLIMIT */ diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c index 23b40b6..7b24449 100644 --- a/sandbox-seccomp-filter.c +++ b/sandbox-seccomp-filter.c @@ -49,6 +49,8 @@ #include #include +#include + #include #include #include @@ -180,12 +182,12 @@ /* Use this for both __NR_futex and __NR_futex_time64 */ # define SC_FUTEX(_nr) \ - SC_ALLOW_FUTEX_OP(__NR_futex, FUTEX_WAIT), \ - SC_ALLOW_FUTEX_OP(__NR_futex, FUTEX_WAIT_BITSET), \ - SC_ALLOW_FUTEX_OP(__NR_futex, FUTEX_WAKE), \ - SC_ALLOW_FUTEX_OP(__NR_futex, FUTEX_WAKE_BITSET), \ - SC_ALLOW_FUTEX_OP(__NR_futex, FUTEX_REQUEUE), \ - SC_ALLOW_FUTEX_OP(__NR_futex, FUTEX_CMP_REQUEUE) + SC_ALLOW_FUTEX_OP(_nr, FUTEX_WAIT), \ + SC_ALLOW_FUTEX_OP(_nr, FUTEX_WAIT_BITSET), \ + SC_ALLOW_FUTEX_OP(_nr, FUTEX_WAKE), \ + SC_ALLOW_FUTEX_OP(_nr, FUTEX_WAKE_BITSET), \ + SC_ALLOW_FUTEX_OP(_nr, FUTEX_REQUEUE), \ + SC_ALLOW_FUTEX_OP(_nr, FUTEX_CMP_REQUEUE) #endif /* __NR_futex || __NR_futex_time64 */ #if defined(__NR_mmap) || defined(__NR_mmap2) @@ -200,6 +202,32 @@ SC_ALLOW_ARG_MASK(_nr, 2, PROT_READ|PROT_WRITE|PROT_NONE) #endif /* __NR_mmap || __NR_mmap2 */ +/* Special handling for setsockopt(2) */ +#define SC_ALLOW_SETSOCKOPT(_level, _optname) \ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_setsockopt, 0, 10), \ + /* load and test level, low word */ \ + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ + offsetof(struct seccomp_data, args[1]) + ARG_LO_OFFSET), \ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \ + ((_level) & 0xFFFFFFFF), 0, 7), \ + /* load and test level high word is zero */ \ + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ + offsetof(struct seccomp_data, args[1]) + ARG_HI_OFFSET), \ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 5), \ + /* load and test optname, low word */ \ + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ + offsetof(struct seccomp_data, args[2]) + ARG_LO_OFFSET), \ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \ + ((_optname) & 0xFFFFFFFF), 0, 3), \ + /* load and test level high word is zero */ \ + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ + offsetof(struct seccomp_data, args[2]) + ARG_HI_OFFSET), \ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 1), \ + BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW), \ + /* reload syscall number; all rules expect it in accumulator */ \ + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ + offsetof(struct seccomp_data, nr)) + /* Syscall filtering set for preauth. */ static const struct sock_filter preauth_insns[] = { /* Ensure the syscall arch convention is as expected. */ @@ -377,6 +405,9 @@ static const struct sock_filter preauth_insns[] = { #ifdef __NR_read SC_ALLOW(__NR_read), #endif +#ifdef __NR_riscv_hwprobe + SC_ALLOW(__NR_riscv_hwprobe), +#endif #ifdef __NR_rt_sigprocmask SC_ALLOW(__NR_rt_sigprocmask), #endif @@ -398,7 +429,26 @@ static const struct sock_filter preauth_insns[] = { #ifdef __NR_writev SC_ALLOW(__NR_writev), #endif +#ifdef __NR_getsockopt + SC_ALLOW(__NR_getsockopt), +#endif +#ifdef __NR_getsockname + SC_ALLOW(__NR_getsockname), +#endif +#ifdef __NR_getpeername + SC_ALLOW(__NR_getpeername), +#endif +#ifdef __NR_uname + SC_ALLOW(__NR_uname), +#endif +#ifdef __NR_setsockopt + SC_ALLOW_SETSOCKOPT(IPPROTO_IPV6, IPV6_TCLASS), + SC_ALLOW_SETSOCKOPT(IPPROTO_IP, IP_TOS), +#endif #ifdef __NR_socketcall + SC_ALLOW_ARG(__NR_socketcall, 0, SYS_GETPEERNAME), + SC_ALLOW_ARG(__NR_socketcall, 0, SYS_GETSOCKNAME), + SC_ALLOW_ARG(__NR_socketcall, 0, SYS_GETSOCKOPT), SC_ALLOW_ARG(__NR_socketcall, 0, SYS_SHUTDOWN), SC_DENY(__NR_socketcall, EACCES), #endif @@ -430,7 +480,7 @@ static const struct sock_fprog preauth_program = { }; struct ssh_sandbox { - pid_t child_pid; + int junk; }; struct ssh_sandbox * @@ -442,10 +492,8 @@ ssh_sandbox_init(struct monitor *monitor) * Strictly, we don't need to maintain any state here but we need * to return non-NULL to satisfy the API. */ - debug3("%s: preparing seccomp filter sandbox", __func__); + debug3_f("preparing seccomp filter sandbox"); box = xcalloc(1, sizeof(*box)); - box->child_pid = 0; - return box; } @@ -471,7 +519,7 @@ ssh_sandbox_child_debugging(void) struct sigaction act; sigset_t mask; - debug3("%s: installing SIGSYS handler", __func__); + debug3_f("installing SIGSYS handler"); memset(&act, 0, sizeof(act)); sigemptyset(&mask); sigaddset(&mask, SIGSYS); @@ -479,7 +527,7 @@ ssh_sandbox_child_debugging(void) act.sa_sigaction = &ssh_sandbox_violation; act.sa_flags = SA_SIGINFO; if (sigaction(SIGSYS, &act, NULL) == -1) - fatal("%s: sigaction(SIGSYS): %s", __func__, strerror(errno)); + fatal_f("sigaction(SIGSYS): %s", strerror(errno)); if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1) fatal("%s: sigprocmask(SIGSYS): %s", __func__, strerror(errno)); @@ -512,13 +560,13 @@ ssh_sandbox_child(struct ssh_sandbox *box) ssh_sandbox_child_debugging(); #endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ - debug3("%s: setting PR_SET_NO_NEW_PRIVS", __func__); + debug3_f("setting PR_SET_NO_NEW_PRIVS"); if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1) { debug("%s: prctl(PR_SET_NO_NEW_PRIVS): %s", __func__, strerror(errno)); nnp_failed = 1; } - debug3("%s: attaching seccomp filter program", __func__); + debug3_f("attaching seccomp filter program"); if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &preauth_program) == -1) debug("%s: prctl(PR_SET_SECCOMP): %s", __func__, strerror(errno)); @@ -527,17 +575,4 @@ ssh_sandbox_child(struct ssh_sandbox *box) "PR_SET_NO_NEW_PRIVS failed", __func__); } -void -ssh_sandbox_parent_finish(struct ssh_sandbox *box) -{ - free(box); - debug3("%s: finished", __func__); -} - -void -ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) -{ - box->child_pid = child_pid; -} - #endif /* SANDBOX_SECCOMP_FILTER */ diff --git a/sandbox-solaris.c b/sandbox-solaris.c index 56ddb9a..0b88c71 100644 --- a/sandbox-solaris.c +++ b/sandbox-solaris.c @@ -97,18 +97,4 @@ ssh_sandbox_child(struct ssh_sandbox *box) fatal("setppriv: %s", strerror(errno)); } -void -ssh_sandbox_parent_finish(struct ssh_sandbox *box) -{ - priv_freeset(box->pset); - box->pset = NULL; - free(box); -} - -void -ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) -{ - /* Nothing to do here */ -} - #endif /* SANDBOX_SOLARIS */ diff --git a/sandbox-systrace.c b/sandbox-systrace.c deleted file mode 100644 index e61d581..0000000 --- a/sandbox-systrace.c +++ /dev/null @@ -1,218 +0,0 @@ -/* $OpenBSD: sandbox-systrace.c,v 1.18 2015/10/02 01:39:26 deraadt Exp $ */ -/* - * Copyright (c) 2011 Damien Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, 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. - */ - -#include "includes.h" - -#ifdef SANDBOX_SYSTRACE - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "atomicio.h" -#include "log.h" -#include "ssh-sandbox.h" -#include "xmalloc.h" - -struct sandbox_policy { - int syscall; - int action; -}; - -/* Permitted syscalls in preauth. Unlisted syscalls get SYSTR_POLICY_KILL */ -static const struct sandbox_policy preauth_policy[] = { - { SYS_exit, SYSTR_POLICY_PERMIT }, -#ifdef SYS_kbind - { SYS_kbind, SYSTR_POLICY_PERMIT }, -#endif - - { SYS_getpid, SYSTR_POLICY_PERMIT }, - { SYS_getpgid, SYSTR_POLICY_PERMIT }, - { SYS_clock_gettime, SYSTR_POLICY_PERMIT }, - { SYS_gettimeofday, SYSTR_POLICY_PERMIT }, - { SYS_nanosleep, SYSTR_POLICY_PERMIT }, - { SYS_sigprocmask, SYSTR_POLICY_PERMIT }, - -#ifdef SYS_getentropy - /* OpenBSD 5.6 and newer use getentropy(2) to seed arc4random(3). */ - { SYS_getentropy, SYSTR_POLICY_PERMIT }, -#else - /* Previous releases used sysctl(3)'s kern.arnd variable. */ - { SYS___sysctl, SYSTR_POLICY_PERMIT }, -#endif -#ifdef SYS_sendsyslog - { SYS_sendsyslog, SYSTR_POLICY_PERMIT }, -#endif - - { SYS_madvise, SYSTR_POLICY_PERMIT }, - { SYS_mmap, SYSTR_POLICY_PERMIT }, - { SYS_mprotect, SYSTR_POLICY_PERMIT }, - { SYS_mquery, SYSTR_POLICY_PERMIT }, - { SYS_munmap, SYSTR_POLICY_PERMIT }, - - { SYS_poll, SYSTR_POLICY_PERMIT }, - { SYS_select, SYSTR_POLICY_PERMIT }, - { SYS_read, SYSTR_POLICY_PERMIT }, - { SYS_write, SYSTR_POLICY_PERMIT }, - { SYS_shutdown, SYSTR_POLICY_PERMIT }, - { SYS_close, SYSTR_POLICY_PERMIT }, - - { SYS_open, SYSTR_POLICY_NEVER }, - - { -1, -1 } -}; - -struct ssh_sandbox { - int systrace_fd; - pid_t child_pid; - void (*osigchld)(int); -}; - -struct ssh_sandbox * -ssh_sandbox_init(struct monitor *monitor) -{ - struct ssh_sandbox *box; - - debug3("%s: preparing systrace sandbox", __func__); - box = xcalloc(1, sizeof(*box)); - box->systrace_fd = -1; - box->child_pid = 0; - box->osigchld = ssh_signal(SIGCHLD, SIG_IGN); - - return box; -} - -void -ssh_sandbox_child(struct ssh_sandbox *box) -{ - debug3("%s: ready", __func__); - ssh_signal(SIGCHLD, box->osigchld); - if (kill(getpid(), SIGSTOP) != 0) - fatal("%s: kill(%d, SIGSTOP)", __func__, getpid()); - debug3("%s: started", __func__); -} - -static void -ssh_sandbox_parent(struct ssh_sandbox *box, pid_t child_pid, - const struct sandbox_policy *allowed_syscalls) -{ - int dev_systrace, i, j, found, status; - pid_t pid; - struct systrace_policy policy; - - /* Wait for the child to send itself a SIGSTOP */ - debug3("%s: wait for child %ld", __func__, (long)child_pid); - do { - pid = waitpid(child_pid, &status, WUNTRACED); - } while (pid == -1 && errno == EINTR); - ssh_signal(SIGCHLD, box->osigchld); - if (!WIFSTOPPED(status)) { - if (WIFSIGNALED(status)) - fatal("%s: child terminated with signal %d", - __func__, WTERMSIG(status)); - if (WIFEXITED(status)) - fatal("%s: child exited with status %d", - __func__, WEXITSTATUS(status)); - fatal("%s: child not stopped", __func__); - } - debug3("%s: child %ld stopped", __func__, (long)child_pid); - box->child_pid = child_pid; - - /* Set up systracing of child */ - if ((dev_systrace = open("/dev/systrace", O_RDONLY)) == -1) - fatal("%s: open(\"/dev/systrace\"): %s", __func__, - strerror(errno)); - if (ioctl(dev_systrace, STRIOCCLONE, &box->systrace_fd) == -1) - fatal("%s: ioctl(STRIOCCLONE, %d): %s", __func__, - dev_systrace, strerror(errno)); - close(dev_systrace); - debug3("%s: systrace attach, fd=%d", __func__, box->systrace_fd); - if (ioctl(box->systrace_fd, STRIOCATTACH, &child_pid) == -1) - fatal("%s: ioctl(%d, STRIOCATTACH, %d): %s", __func__, - box->systrace_fd, child_pid, strerror(errno)); - - /* Allocate and assign policy */ - memset(&policy, 0, sizeof(policy)); - policy.strp_op = SYSTR_POLICY_NEW; - policy.strp_maxents = SYS_MAXSYSCALL; - if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1) - fatal("%s: ioctl(%d, STRIOCPOLICY (new)): %s", __func__, - box->systrace_fd, strerror(errno)); - - policy.strp_op = SYSTR_POLICY_ASSIGN; - policy.strp_pid = box->child_pid; - if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1) - fatal("%s: ioctl(%d, STRIOCPOLICY (assign)): %s", - __func__, box->systrace_fd, strerror(errno)); - - /* Set per-syscall policy */ - for (i = 0; i < SYS_MAXSYSCALL; i++) { - found = 0; - for (j = 0; allowed_syscalls[j].syscall != -1; j++) { - if (allowed_syscalls[j].syscall == i) { - found = 1; - break; - } - } - policy.strp_op = SYSTR_POLICY_MODIFY; - policy.strp_code = i; - policy.strp_policy = found ? - allowed_syscalls[j].action : SYSTR_POLICY_KILL; - if (found) - debug3("%s: policy: enable syscall %d", __func__, i); - if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1) - fatal("%s: ioctl(%d, STRIOCPOLICY (modify)): %s", - __func__, box->systrace_fd, strerror(errno)); - } - - /* Signal the child to start running */ - debug3("%s: start child %ld", __func__, (long)child_pid); - if (kill(box->child_pid, SIGCONT) != 0) - fatal("%s: kill(%d, SIGCONT)", __func__, box->child_pid); -} - -void -ssh_sandbox_parent_finish(struct ssh_sandbox *box) -{ - /* Closing this before the child exits will terminate it */ - close(box->systrace_fd); - - free(box); - debug3("%s: finished", __func__); -} - -void -ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) -{ - ssh_sandbox_parent(box, child_pid, preauth_policy); -} - -#endif /* SANDBOX_SYSTRACE */ diff --git a/scp.0 b/scp.0 index b514c69..d59fe31 100644 --- a/scp.0 +++ b/scp.0 @@ -11,7 +11,7 @@ SYNOPSIS DESCRIPTION scp copies files between hosts on a network. - scp uses the SFTP protocol over a ssh(1) connection for data transfer, + scp uses the SFTP protocol over an ssh(1) connection for data transfer, and uses the same authentication and provides the same security as a login session. @@ -30,11 +30,11 @@ DESCRIPTION The options are as follows: -3 Copies between two remote hosts are transferred through the local - host. Without this option the data is copied directly between - the two remote hosts. Note that, when using the legacy SCP - protocol (via the -O flag), this option selects batch mode for - the second host as scp cannot ask for passwords or passphrases - for both hosts. This mode is the default. + host. This mode is the default, but see also the -R option for + copying data directly between two remote hosts. Note that when + using the legacy SCP protocol (via the -O flag), this option + selects batch mode for the second host as scp cannot ask for + passwords or passphrases for both hosts. -4 Forces scp to use IPv4 addresses only. @@ -91,67 +91,106 @@ DESCRIPTION the options listed below, and their possible values, see ssh_config(5). + AddKeysToAgent AddressFamily BatchMode BindAddress BindInterface + CASignatureAlgorithms CanonicalDomains CanonicalizeFallbackLocal CanonicalizeHostname CanonicalizeMaxDots CanonicalizePermittedCNAMEs - CASignatureAlgorithms CertificateFile + ChannelTimeout CheckHostIP Ciphers + ClearAllForwardings Compression - ConnectionAttempts ConnectTimeout + ConnectionAttempts ControlMaster ControlPath ControlPersist - GlobalKnownHostsFile + DynamicForward + EnableEscapeCommandline + EnableSSHKeysign + EscapeChar + ExitOnForwardFailure + FingerprintHash + ForkAfterAuthentication + ForwardAgent + ForwardX11 + ForwardX11Timeout + ForwardX11Trusted GSSAPIAuthentication GSSAPIDelegateCredentials + GatewayPorts + GlobalKnownHostsFile HashKnownHosts Host - HostbasedAcceptedAlgorithms - HostbasedAuthentication HostKeyAlgorithms HostKeyAlias + HostbasedAcceptedAlgorithms + HostbasedAuthentication Hostname + IPQoS IdentitiesOnly IdentityAgent IdentityFile - IPQoS + IgnoreUnknown + Include KbdInteractiveAuthentication KbdInteractiveDevices KexAlgorithms KnownHostsCommand + LocalCommand + LocalForward LogLevel + LogVerbose MACs NoHostAuthenticationForLocalhost NumberOfPasswordPrompts - PasswordAuthentication + ObscureKeystrokeTiming PKCS11Provider + PasswordAuthentication + PermitLocalCommand + PermitRemoteOpen Port PreferredAuthentications ProxyCommand ProxyJump + ProxyUseFdpass PubkeyAcceptedAlgorithms PubkeyAuthentication RekeyLimit + RemoteCommand + RemoteForward + RequestTTY RequiredRSASize + RevokedHostKeys + SecurityKeyProvider SendEnv - ServerAliveInterval ServerAliveCountMax + ServerAliveInterval + SessionType SetEnv + StdinNull + StreamLocalBindMask + StreamLocalBindUnlink StrictHostKeyChecking + SyslogFacility TCPKeepAlive + Tag + Tunnel + TunnelDevice UpdateHostKeys User UserKnownHostsFile VerifyHostKeyDNS + VisualHostKey + XAuthLocation -P port Specifies the port to connect to on the remote host. Note that @@ -164,10 +203,12 @@ DESCRIPTION -q Quiet mode: disables the progress meter as well as warning and diagnostic messages from ssh(1). - -R Copies between two remote hosts are performed by connecting to - the origin host and executing scp there. This requires that scp - running on the origin host can authenticate to the destination - host without requiring a password. + -R Copies between two remote hosts are transferred through the local + host by default. This option instead copies between two remote + hosts by connecting to the origin host and executing scp there. + This requires that scp running on the origin host can + authenticate to the destination host without requiring a + password. -r Recursively copy entire directories. Note that scp follows symbolic links encountered in the tree traversal. @@ -229,4 +270,4 @@ CAVEATS requires careful quoting of any characters that have special meaning to the remote shell, such as quote characters. -OpenBSD 7.6 December 16, 2022 OpenBSD 7.6 +OpenBSD 7.8 October 4, 2025 SCP(1) diff --git a/scp.1 b/scp.1 index 54c6fe3..7bce0fe 100644 --- a/scp.1 +++ b/scp.1 @@ -8,9 +8,9 @@ .\" .\" Created: Sun May 7 00:14:37 1995 ylo .\" -.\" $OpenBSD: scp.1,v 1.112 2022/12/16 07:13:22 djm Exp $ +.\" $OpenBSD: scp.1,v 1.115 2025/10/04 21:41:35 naddy Exp $ .\" -.Dd $Mdocdate: December 16 2022 $ +.Dd $Mdocdate: October 4 2025 $ .Dt SCP 1 .Os .Sh NAME @@ -35,7 +35,7 @@ copies files between hosts on a network. .Pp .Nm -uses the SFTP protocol over a +uses the SFTP protocol over an .Xr ssh 1 connection for data transfer, and uses the same authentication and provides the same security as a login session. @@ -76,15 +76,16 @@ The options are as follows: .Bl -tag -width Ds .It Fl 3 Copies between two remote hosts are transferred through the local host. -Without this option the data is copied directly between the two remote -hosts. -Note that, when using the legacy SCP protocol (via the +This mode is the default, +but see also the +.Fl R +option for copying data directly between two remote hosts. +Note that when using the legacy SCP protocol (via the .Fl O flag), this option selects batch mode for the second host as .Nm cannot ask for passwords or passphrases for both hosts. -This mode is the default. .It Fl 4 Forces .Nm @@ -162,67 +163,106 @@ For full details of the options listed below, and their possible values, see .Xr ssh_config 5 . .Pp .Bl -tag -width Ds -offset indent -compact +.It AddKeysToAgent .It AddressFamily .It BatchMode .It BindAddress .It BindInterface +.It CASignatureAlgorithms .It CanonicalDomains .It CanonicalizeFallbackLocal .It CanonicalizeHostname .It CanonicalizeMaxDots .It CanonicalizePermittedCNAMEs -.It CASignatureAlgorithms .It CertificateFile +.It ChannelTimeout .It CheckHostIP .It Ciphers +.It ClearAllForwardings .It Compression -.It ConnectionAttempts .It ConnectTimeout +.It ConnectionAttempts .It ControlMaster .It ControlPath .It ControlPersist -.It GlobalKnownHostsFile +.It DynamicForward +.It EnableEscapeCommandline +.It EnableSSHKeysign +.It EscapeChar +.It ExitOnForwardFailure +.It FingerprintHash +.It ForkAfterAuthentication +.It ForwardAgent +.It ForwardX11 +.It ForwardX11Timeout +.It ForwardX11Trusted .It GSSAPIAuthentication .It GSSAPIDelegateCredentials +.It GatewayPorts +.It GlobalKnownHostsFile .It HashKnownHosts .It Host -.It HostbasedAcceptedAlgorithms -.It HostbasedAuthentication .It HostKeyAlgorithms .It HostKeyAlias +.It HostbasedAcceptedAlgorithms +.It HostbasedAuthentication .It Hostname +.It IPQoS .It IdentitiesOnly .It IdentityAgent .It IdentityFile -.It IPQoS +.It IgnoreUnknown +.It Include .It KbdInteractiveAuthentication .It KbdInteractiveDevices .It KexAlgorithms .It KnownHostsCommand +.It LocalCommand +.It LocalForward .It LogLevel +.It LogVerbose .It MACs .It NoHostAuthenticationForLocalhost .It NumberOfPasswordPrompts -.It PasswordAuthentication +.It ObscureKeystrokeTiming .It PKCS11Provider +.It PasswordAuthentication +.It PermitLocalCommand +.It PermitRemoteOpen .It Port .It PreferredAuthentications .It ProxyCommand .It ProxyJump +.It ProxyUseFdpass .It PubkeyAcceptedAlgorithms .It PubkeyAuthentication .It RekeyLimit +.It RemoteCommand +.It RemoteForward +.It RequestTTY .It RequiredRSASize +.It RevokedHostKeys +.It SecurityKeyProvider .It SendEnv -.It ServerAliveInterval .It ServerAliveCountMax +.It ServerAliveInterval +.It SessionType .It SetEnv +.It StdinNull +.It StreamLocalBindMask +.It StreamLocalBindUnlink .It StrictHostKeyChecking +.It SyslogFacility .It TCPKeepAlive +.It Tag +.It Tunnel +.It TunnelDevice .It UpdateHostKeys .It User .It UserKnownHostsFile .It VerifyHostKeyDNS +.It VisualHostKey +.It XAuthLocation .El .It Fl P Ar port Specifies the port to connect to on the remote host. @@ -239,7 +279,9 @@ Quiet mode: disables the progress meter as well as warning and diagnostic messages from .Xr ssh 1 . .It Fl R -Copies between two remote hosts are performed by connecting to the origin +Copies between two remote hosts are transferred through the local host +by default. +This option instead copies between two remote hosts by connecting to the origin host and executing .Nm there. diff --git a/scp.c b/scp.c index 0779c3c..1faa9a5 100644 --- a/scp.c +++ b/scp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: scp.c,v 1.261 2024/06/26 23:14:14 deraadt Exp $ */ +/* $OpenBSD: scp.c,v 1.273 2026/04/02 07:42:16 djm Exp $ */ /* * scp - secure remote copy. This is basically patched BSD rcp which * uses ssh to do the data transfer (instead of using rcmd). @@ -74,19 +74,8 @@ #include "includes.h" #include -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef HAVE_POLL_H -#include -#else -# ifdef HAVE_SYS_POLL_H -# include -# endif -#endif -#ifdef HAVE_SYS_TIME_H -# include -#endif +#include +#include #include #include @@ -97,30 +86,21 @@ #ifdef HAVE_FNMATCH_H #include #endif -#ifdef USE_SYSTEM_GLOB -# include -#else -# include "openbsd-compat/glob.h" -#endif -#ifdef HAVE_LIBGEN_H +#include #include -#endif -#include -#ifdef HAVE_UTIL_H -# include -#endif #include +#include #include #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include #include #include #include +#include +#include #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS) #include #endif @@ -172,7 +152,7 @@ int throughlocal = 1; /* Non-standard port to use for the ssh connection or -1. */ int sshport = -1; -/* This is the program to execute for the secured connection. ("ssh" or -S) */ +/* This is the program to execute for the secure connection. ("ssh" or -S) */ char *ssh_program = _PATH_SSH_PROGRAM; /* This is used to store the pid of ssh_program */ @@ -232,7 +212,7 @@ suspchild(int signo) static int do_local_cmd(arglist *a) { - u_int i; + char *cp; int status; pid_t pid; @@ -240,10 +220,9 @@ do_local_cmd(arglist *a) fatal("do_local_cmd: no arguments"); if (verbose_mode) { - fprintf(stderr, "Executing:"); - for (i = 0; i < a->num; i++) - fmprintf(stderr, " %s", a->list[i]); - fprintf(stderr, "\n"); + cp = argv_assemble(a->num, a->list); + fmprintf(stderr, "Executing: %s\n", cp); + free(cp); } if ((pid = fork()) == -1) fatal("do_local_cmd: fork: %s", strerror(errno)); @@ -505,6 +484,7 @@ main(int argc, char **argv) addargs(&args, "-oClearAllForwardings=yes"); addargs(&args, "-oRemoteCommand=none"); addargs(&args, "-oRequestTTY=no"); + addargs(&args, "-oControlMaster=no"); fflag = Tflag = tflag = 0; while ((ch = getopt(argc, argv, @@ -985,7 +965,7 @@ brace_expand(const char *pattern, char ***patternsp, size_t *npatternsp) continue; } /* - * Pattern did not expand; append the finename component to + * Pattern did not expand; append the filename component to * the completed list */ if ((cp2 = strrchr(cp, '/')) != NULL) @@ -1085,8 +1065,9 @@ toremote(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct) } if (host && throughlocal) { /* extended remote to remote */ if (mode == MODE_SFTP) { - if (remin == -1) { + if (remin == -1 || conn == NULL) { /* Connect to dest now */ + sftp_free(conn); conn = do_sftp_connect(thost, tuser, tport, sftp_direct, &remin, &remout, &do_cmd_pid); @@ -1104,6 +1085,7 @@ toremote(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct) * scp -3 hosta:/foo hosta:/bar hostb: */ /* Connect to origin now */ + sftp_free(conn2); conn2 = do_sftp_connect(host, suser, sport, sftp_direct, &remin2, &remout2, &do_cmd_pid2); @@ -1193,6 +1175,7 @@ toremote(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct) } if (remin == -1) { /* Connect to remote now */ + sftp_free(conn); conn = do_sftp_connect(thost, tuser, tport, sftp_direct, &remin, &remout, &do_cmd_pid); @@ -1221,14 +1204,15 @@ toremote(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct) } } out: - if (mode == MODE_SFTP) - free(conn); + freeargs(&alist); free(tuser); free(thost); free(targ); free(suser); free(host); free(src); + sftp_free(conn); + sftp_free(conn2); } void @@ -1274,6 +1258,7 @@ tolocal(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct) } /* Remote to local. */ if (mode == MODE_SFTP) { + sftp_free(conn); conn = do_sftp_connect(host, suser, sport, sftp_direct, &remin, &remout, &do_cmd_pid); if (conn == NULL) { @@ -1285,7 +1270,6 @@ tolocal(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct) /* The protocol */ sink_sftp(1, argv[argc - 1], src, conn); - free(conn); (void) close(remin); (void) close(remout); remin = remout = -1; @@ -1305,9 +1289,11 @@ tolocal(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct) (void) close(remin); remin = remout = -1; } + freeargs(&alist); free(suser); free(host); free(src); + sftp_free(conn); } /* Prepare remote path, handling ~ by assuming cwd is the homedir */ @@ -1349,6 +1335,10 @@ source_sftp(int argc, char *src, char *targ, struct sftp_conn *conn) if ((filename = basename(src)) == NULL) fatal("basename \"%s\": %s", src, strerror(errno)); + /* Special handling for source of '..' */ + if (strcmp(filename, "..") == 0) + filename = "."; /* Upload to dest, not dest/.. */ + /* * No need to glob here - the local shell already took care of * the expansions @@ -1581,7 +1571,7 @@ sink_sftp(int argc, char *dst, const char *src, struct sftp_conn *conn) } /* Did we actually get any matches back from the glob? */ - if (g.gl_matchc == 0 && g.gl_pathc == 1 && g.gl_pathv[0] != 0) { + if (g.gl_matchc == 0 && g.gl_pathc == 1 && g.gl_pathv[0] != NULL) { /* * If nothing matched but a path returned, then it's probably * a GLOB_NOCHECK result. Check whether the unglobbed path @@ -1622,6 +1612,10 @@ sink_sftp(int argc, char *dst, const char *src, struct sftp_conn *conn) goto out; } + /* Special handling for destination of '..' */ + if (strcmp(filename, "..") == 0) + filename = "."; /* Download to dest, not dest/.. */ + if (dst_is_dir) abs_dst = sftp_path_append(dst, filename); else @@ -1684,8 +1678,10 @@ sink(int argc, char **argv, const char *src) setimes = targisdir = 0; mask = umask(0); - if (!pflag) + if (!pflag) { + mask |= 07000; (void) umask(mask); + } if (argc != 1) { run_err("ambiguous target"); exit(1); @@ -1889,7 +1885,7 @@ bad: run_err("%s: %s", np, strerror(errno)); /* * NB. do not use run_err() unless immediately followed by * exit() below as it may send a spurious reply that might - * desyncronise us from the peer. Use note_err() instead. + * desynchronise us from the peer. Use note_err() instead. */ statbytes = 0; if (showprogress) @@ -2022,7 +2018,7 @@ throughlocal_sftp(struct sftp_conn *from, struct sftp_conn *to, } /* Did we actually get any matches back from the glob? */ - if (g.gl_matchc == 0 && g.gl_pathc == 1 && g.gl_pathv[0] != 0) { + if (g.gl_matchc == 0 && g.gl_pathc == 1 && g.gl_pathv[0] != NULL) { /* * If nothing matched but a path returned, then it's probably * a GLOB_NOCHECK result. Check whether the unglobbed path @@ -2232,7 +2228,7 @@ allocbuf(BUF *bp, int fd, int blksize) if (fstat(fd, &stb) == -1) { run_err("fstat: %s", strerror(errno)); - return (0); + return (NULL); } size = ROUNDUP(stb.st_blksize, blksize); if (size == 0) diff --git a/servconf.c b/servconf.c index bef1b51..668259a 100644 --- a/servconf.c +++ b/servconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.c,v 1.419 2024/09/25 01:24:04 djm Exp $ */ +/* $OpenBSD: servconf.c,v 1.446 2026/04/02 07:38:14 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -14,19 +14,20 @@ #include #include +#include #include #ifdef __OpenBSD__ #include #endif #include -#include #include #ifdef HAVE_NET_ROUTE_H #include #endif #include +#include #include #include #include @@ -37,16 +38,8 @@ #include #include #include -#ifdef HAVE_UTIL_H #include -#endif -#ifdef USE_SYSTEM_GLOB -# include -#else -# include "openbsd-compat/glob.h" -#endif -#include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "ssh.h" #include "log.h" @@ -68,6 +61,7 @@ #include "auth.h" #include "myproposal.h" #include "digest.h" +#include "version.h" #if !defined(SSHD_PAM_SERVICE) # define SSHD_PAM_SERVICE "sshd" @@ -138,6 +132,7 @@ initialize_server_options(ServerOptions *options) options->kerberos_get_afs_token = -1; options->gss_authentication=-1; options->gss_cleanup_creds = -1; + options->gss_deleg_creds = -1; options->gss_strict_acceptor = -1; options->password_authentication = -1; options->kbd_interactive_authentication = -1; @@ -174,13 +169,14 @@ initialize_server_options(ServerOptions *options) options->per_source_penalty.max_sources6 = -1; options->per_source_penalty.overflow_mode = -1; options->per_source_penalty.overflow_mode6 = -1; - options->per_source_penalty.penalty_crash = -1; - options->per_source_penalty.penalty_authfail = -1; - options->per_source_penalty.penalty_noauth = -1; - options->per_source_penalty.penalty_grace = -1; - options->per_source_penalty.penalty_refuseconnection = -1; - options->per_source_penalty.penalty_max = -1; - options->per_source_penalty.penalty_min = -1; + options->per_source_penalty.penalty_crash = -1.0; + options->per_source_penalty.penalty_authfail = -1.0; + options->per_source_penalty.penalty_invaliduser = -1.0; + options->per_source_penalty.penalty_noauth = -1.0; + options->per_source_penalty.penalty_grace = -1.0; + options->per_source_penalty.penalty_refuseconnection = -1.0; + options->per_source_penalty.penalty_max = -1.0; + options->per_source_penalty.penalty_min = -1.0; options->max_authtries = -1; options->max_sessions = -1; options->banner = NULL; @@ -197,7 +193,8 @@ initialize_server_options(ServerOptions *options) options->chroot_directory = NULL; options->authorized_keys_command = NULL; options->authorized_keys_command_user = NULL; - options->revoked_keys_file = NULL; + options->revoked_keys_files = NULL; + options->num_revoked_keys_files = 0; options->sk_provider = NULL; options->trusted_user_ca_keys = NULL; options->authorized_principals_file = NULL; @@ -214,6 +211,7 @@ initialize_server_options(ServerOptions *options) options->num_channel_timeouts = 0; options->unused_connection_timeout = -1; options->sshd_session_path = NULL; + options->sshd_auth_path = NULL; options->refuse_connection = -1; } @@ -312,10 +310,6 @@ fill_default_server_options(ServerOptions *options) #endif servconf_add_hostkey("[default]", 0, options, _PATH_HOST_ED25519_KEY_FILE, 0); -#ifdef WITH_XMSS - servconf_add_hostkey("[default]", 0, options, - _PATH_HOST_XMSS_KEY_FILE, 0); -#endif /* WITH_XMSS */ } /* No certificates by default */ if (options->num_ports == 0) @@ -380,6 +374,8 @@ fill_default_server_options(ServerOptions *options) options->gss_authentication = 0; if (options->gss_cleanup_creds == -1) options->gss_cleanup_creds = 1; + if (options->gss_deleg_creds == -1) + options->gss_deleg_creds = 1; if (options->gss_strict_acceptor == -1) options->gss_strict_acceptor = 1; if (options->password_authentication == -1) @@ -433,20 +429,22 @@ fill_default_server_options(ServerOptions *options) options->per_source_penalty.overflow_mode = PER_SOURCE_PENALTY_OVERFLOW_PERMISSIVE; if (options->per_source_penalty.overflow_mode6 == -1) options->per_source_penalty.overflow_mode6 = options->per_source_penalty.overflow_mode; - if (options->per_source_penalty.penalty_crash == -1) - options->per_source_penalty.penalty_crash = 90; - if (options->per_source_penalty.penalty_grace == -1) - options->per_source_penalty.penalty_grace = 10; - if (options->per_source_penalty.penalty_authfail == -1) - options->per_source_penalty.penalty_authfail = 5; - if (options->per_source_penalty.penalty_noauth == -1) - options->per_source_penalty.penalty_noauth = 1; - if (options->per_source_penalty.penalty_refuseconnection == -1) - options->per_source_penalty.penalty_refuseconnection = 10; - if (options->per_source_penalty.penalty_min == -1) - options->per_source_penalty.penalty_min = 15; - if (options->per_source_penalty.penalty_max == -1) - options->per_source_penalty.penalty_max = 600; + if (options->per_source_penalty.penalty_crash < 0.0) + options->per_source_penalty.penalty_crash = 90.0; + if (options->per_source_penalty.penalty_grace < 0.0) + options->per_source_penalty.penalty_grace = 10.0; + if (options->per_source_penalty.penalty_authfail < 0.0) + options->per_source_penalty.penalty_authfail = 5.0; + if (options->per_source_penalty.penalty_invaliduser < 0.0) + options->per_source_penalty.penalty_invaliduser = 5.0; + if (options->per_source_penalty.penalty_noauth < 0.0) + options->per_source_penalty.penalty_noauth = 1.0; + if (options->per_source_penalty.penalty_refuseconnection < 0.0) + options->per_source_penalty.penalty_refuseconnection = 10.0; + if (options->per_source_penalty.penalty_min < 0.0) + options->per_source_penalty.penalty_min = 15.0; + if (options->per_source_penalty.penalty_max < 0.0) + options->per_source_penalty.penalty_max = 600.0; if (options->max_authtries == -1) options->max_authtries = DEFAULT_AUTH_FAIL_MAX; if (options->max_sessions == -1) @@ -470,9 +468,9 @@ fill_default_server_options(ServerOptions *options) if (options->permit_tun == -1) options->permit_tun = SSH_TUNMODE_NO; if (options->ip_qos_interactive == -1) - options->ip_qos_interactive = IPTOS_DSCP_AF21; + options->ip_qos_interactive = IPTOS_DSCP_EF; if (options->ip_qos_bulk == -1) - options->ip_qos_bulk = IPTOS_DSCP_CS1; + options->ip_qos_bulk = IPTOS_DSCP_CS0; if (options->version_addendum == NULL) options->version_addendum = xstrdup(""); if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) @@ -493,6 +491,8 @@ fill_default_server_options(ServerOptions *options) options->unused_connection_timeout = 0; if (options->sshd_session_path == NULL) options->sshd_session_path = xstrdup(_PATH_SSHD_SESSION); + if (options->sshd_auth_path == NULL) + options->sshd_auth_path = xstrdup(_PATH_SSHD_AUTH); if (options->refuse_connection == -1) options->refuse_connection = 0; @@ -519,7 +519,6 @@ fill_default_server_options(ServerOptions *options) CLEAR_ON_NONE(options->xauth_location); CLEAR_ON_NONE(options->banner); CLEAR_ON_NONE(options->trusted_user_ca_keys); - CLEAR_ON_NONE(options->revoked_keys_file); CLEAR_ON_NONE(options->sk_provider); CLEAR_ON_NONE(options->authorized_principals_file); CLEAR_ON_NONE(options->adm_forced_command); @@ -535,6 +534,8 @@ fill_default_server_options(ServerOptions *options) CLEAR_ON_NONE_ARRAY(channel_timeouts, num_channel_timeouts, "none"); CLEAR_ON_NONE_ARRAY(auth_methods, num_auth_methods, "any"); + CLEAR_ON_NONE_ARRAY(revoked_keys_files, num_revoked_keys_files, "none"); + CLEAR_ON_NONE_ARRAY(authorized_keys_files, num_authkeys_files, "none"); #undef CLEAR_ON_NONE #undef CLEAR_ON_NONE_ARRAY } @@ -563,7 +564,7 @@ typedef enum { sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, sPerSourcePenalties, sPerSourcePenaltyExemptList, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, - sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, + sGssAuthentication, sGssCleanupCreds, sGssDelegateCreds, sGssStrictAcceptor, sAcceptEnv, sSetEnv, sPermitTunnel, sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, @@ -577,7 +578,7 @@ typedef enum { sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider, sRequiredRSASize, sChannelTimeout, sUnusedConnectionTimeout, - sSshdSessionPath, sRefuseConnection, + sSshdSessionPath, sSshdAuthPath, sRefuseConnection, sDeprecated, sIgnore, sUnsupported } ServerOpCodes; @@ -649,10 +650,12 @@ static struct { #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, + { "gssapidelegatecredentials", sGssDelegateCreds, SSHCFG_GLOBAL }, { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, #else { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, + { "gssapidelegatecredentials", sUnsupported, SSHCFG_GLOBAL }, { "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL }, #endif { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, @@ -745,6 +748,7 @@ static struct { { "channeltimeout", sChannelTimeout, SSHCFG_ALL }, { "unusedconnectiontimeout", sUnusedConnectionTimeout, SSHCFG_ALL }, { "sshdsessionpath", sSshdSessionPath, SSHCFG_GLOBAL }, + { "sshdauthpath", sSshdAuthPath, SSHCFG_GLOBAL }, { "refuseconnection", sRefuseConnection, SSHCFG_ALL }, { NULL, sBadOption, 0 } }; @@ -1035,25 +1039,26 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, int result = 1, attributes = 0, port; char *arg, *attrib = NULL, *oattrib; - if (ci == NULL) - debug3("checking syntax for 'Match %s'", full_line); - else { + if (ci == NULL) { + debug3("checking syntax for 'Match %s' on line %d", + full_line, line); + } else { debug3("checking match for '%s' user %s%s host %s addr %s " - "laddr %s lport %d", full_line, + "laddr %s lport %d on line %d", full_line, ci->user ? ci->user : "(null)", ci->user_invalid ? " (invalid)" : "", ci->host ? ci->host : "(null)", ci->address ? ci->address : "(null)", - ci->laddress ? ci->laddress : "(null)", ci->lport); + ci->laddress ? ci->laddress : "(null)", ci->lport, line); } while ((oattrib = argv_next(acp, avp)) != NULL) { - attrib = xstrdup(oattrib); /* Terminate on comment */ - if (*attrib == '#') { + if (*oattrib == '#') { argv_consume(acp); /* mark all arguments consumed */ break; } + attrib = xstrdup(oattrib); arg = NULL; attributes++; /* Criterion "all" has no argument and must appear alone */ @@ -1075,13 +1080,13 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, if (strcasecmp(attrib, "invalid-user") == 0) { if (ci == NULL) { result = 0; - continue; + goto next; } if (ci->user_invalid == 0) result = 0; else debug("matched invalid-user at line %d", line); - continue; + goto next; } /* Keep this list in sync with below */ @@ -1091,7 +1096,8 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, strprefix(attrib, "address=", 1) != NULL || strprefix(attrib, "localaddress=", 1) != NULL || strprefix(attrib, "localport=", 1) != NULL || - strprefix(attrib, "rdomain=", 1) != NULL) { + strprefix(attrib, "rdomain=", 1) != NULL || + strprefix(attrib, "version=", 1) != NULL) { arg = strchr(attrib, '='); *(arg++) = '\0'; } else { @@ -1107,7 +1113,7 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, if (strcasecmp(attrib, "user") == 0) { if (ci == NULL || (ci->test && ci->user == NULL)) { result = 0; - continue; + goto next; } if (ci->user == NULL) match_test_missing_fatal("User", "user"); @@ -1119,7 +1125,7 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, } else if (strcasecmp(attrib, "group") == 0) { if (ci == NULL || (ci->test && ci->user == NULL)) { result = 0; - continue; + goto next; } if (ci->user == NULL) match_test_missing_fatal("Group", "user"); @@ -1133,7 +1139,7 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, } else if (strcasecmp(attrib, "host") == 0) { if (ci == NULL || (ci->test && ci->host == NULL)) { result = 0; - continue; + goto next; } if (ci->host == NULL) match_test_missing_fatal("Host", "host"); @@ -1148,7 +1154,7 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, fatal("Invalid Match address argument " "'%s' at line %d", arg, line); result = 0; - continue; + goto next; } if (ci->address == NULL) match_test_missing_fatal("Address", "addr"); @@ -1172,7 +1178,7 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, "argument '%s' at line %d", arg, line); result = 0; - continue; + goto next; } if (ci->laddress == NULL) match_test_missing_fatal("LocalAddress", @@ -1200,7 +1206,7 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, } if (ci == NULL || (ci->test && ci->lport == -1)) { result = 0; - continue; + goto next; } if (ci->lport == 0) match_test_missing_fatal("LocalPort", "lport"); @@ -1214,20 +1220,29 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, } else if (strcasecmp(attrib, "rdomain") == 0) { if (ci == NULL || (ci->test && ci->rdomain == NULL)) { result = 0; - continue; + goto next; } if (ci->rdomain == NULL) match_test_missing_fatal("RDomain", "rdomain"); if (match_pattern_list(ci->rdomain, arg, 0) != 1) result = 0; else - debug("user %.100s matched 'RDomain %.100s' at " - "line %d", ci->rdomain, arg, line); + debug("connection RDomain %.100s matched " + "'RDomain %.100s' at line %d", + ci->rdomain, arg, line); + } else if (strcasecmp(attrib, "version") == 0) { + if (match_pattern_list(SSH_RELEASE, arg, 0) != 1) + result = 0; + else + debug("version %.100s matched " + "'version %.100s' at line %d", + SSH_RELEASE, arg, line); } else { error("Unsupported Match attribute %s", oattrib); result = -1; goto out; } + next: free(attrib); attrib = NULL; } @@ -1237,7 +1252,7 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, } out: if (ci != NULL && result != -1) - debug3("match %sfound", result ? "" : "not "); + debug3("match %sfound on line %d", result ? "" : "not ", line); free(attrib); return result; } @@ -1267,8 +1282,8 @@ static const struct multistate multistate_addressfamily[] = { { NULL, -1 } }; static const struct multistate multistate_permitrootlogin[] = { - { "without-password", PERMIT_NO_PASSWD }, { "prohibit-password", PERMIT_NO_PASSWD }, + { "without-password", PERMIT_NO_PASSWD }, { "forced-commands-only", PERMIT_FORCED_ONLY }, { "yes", PERMIT_YES }, { "no", PERMIT_NO }, @@ -1304,7 +1319,8 @@ process_server_config_line_depth(ServerOptions *options, char *line, struct include_list *includes) { char *str, ***chararrayptr, **charptr, *arg, *arg2, *p, *keyword; - int cmdline = 0, *intptr, value, value2, n, port, oactive, r; + int cmdline = 0, *intptr, value, value2, value3, n, port, oactive, r; + double dvalue, *doubleptr = NULL; int ca_only = 0, found = 0; SyslogFacility *log_facility_ptr; LogLevel *log_level_ptr; @@ -1638,6 +1654,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, intptr = &options->gss_cleanup_creds; goto parse_flag; + case sGssDelegateCreds: + intptr = &options->gss_deleg_creds; + goto parse_flag; + case sGssStrictAcceptor: intptr = &options->gss_strict_acceptor; goto parse_flag; @@ -1935,8 +1955,8 @@ process_server_config_line_depth(ServerOptions *options, char *line, break; case sSubsystem: - arg = argv_next(&ac, &av); - if (!arg || *arg == '\0') + if ((arg = argv_next(&ac, &av)) == NULL || *arg == '\0' || + ((arg2 = argv_next(&ac, &av)) == NULL || *arg2 == '\0')) fatal("%s line %d: %s missing argument.", filename, linenum, keyword); if (!*activep) { @@ -1969,15 +1989,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, options->num_subsystems + 1, sizeof(*options->subsystem_args)); options->subsystem_name[options->num_subsystems] = xstrdup(arg); - arg = argv_next(&ac, &av); - if (!arg || *arg == '\0') { - fatal("%s line %d: Missing subsystem command.", - filename, linenum); - } options->subsystem_command[options->num_subsystems] = - xstrdup(arg); + xstrdup(arg2); /* Collect arguments (separate to executable) */ - arg = argv_assemble(1, &arg); /* quote command correctly */ + arg = argv_assemble(1, &arg2); /* quote command correctly */ arg2 = argv_assemble(ac, av); /* rest of command */ xasprintf(&options->subsystem_args[options->num_subsystems], "%s%s%s", arg, *arg2 == '\0' ? "" : " ", arg2); @@ -1992,25 +2007,27 @@ process_server_config_line_depth(ServerOptions *options, char *line, if (!arg || *arg == '\0') fatal("%s line %d: %s missing argument.", filename, linenum, keyword); + /* begin:rate:max */ if ((n = sscanf(arg, "%d:%d:%d", - &options->max_startups_begin, - &options->max_startups_rate, - &options->max_startups)) == 3) { - if (options->max_startups_begin > - options->max_startups || - options->max_startups_rate > 100 || - options->max_startups_rate < 1) + &value, &value2, &value3)) == 3) { + if (value > value3 || value2 > 100 || value2 < 1) fatal("%s line %d: Invalid %s spec.", filename, linenum, keyword); - } else if (n != 1) + } else if (n == 1) { + value3 = value; + value2 = -1; + } else { fatal("%s line %d: Invalid %s spec.", filename, linenum, keyword); - else - options->max_startups = options->max_startups_begin; - if (options->max_startups <= 0 || - options->max_startups_begin <= 0) + } + if (value <= 0 || value3 <= 0) fatal("%s line %d: Invalid %s spec.", filename, linenum, keyword); + if (*activep && options->max_startups == -1) { + options->max_startups_begin = value; + options->max_startups_rate = value2; + options->max_startups = value3; + } break; case sPerSourceNetBlockSize: @@ -2030,9 +2047,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, if (n != 1 && n != 2) fatal("%s line %d: Invalid %s spec.", filename, linenum, keyword); - if (*activep) { + if (*activep && options->per_source_masklen_ipv4 == -1) { options->per_source_masklen_ipv4 = value; - options->per_source_masklen_ipv6 = value2; + if (n == 2) + options->per_source_masklen_ipv6 = value2; } break; @@ -2069,10 +2087,13 @@ process_server_config_line_depth(ServerOptions *options, char *line, case sPerSourcePenalties: while ((arg = argv_next(&ac, &av)) != NULL) { + const char *q = NULL; + found = 1; + intptr = NULL; + doubleptr = NULL; value = -1; value2 = 0; - p = NULL; /* Allow no/yes only in first position */ if (strcasecmp(arg, "no") == 0 || (value2 = (strcasecmp(arg, "yes") == 0))) { @@ -2085,35 +2106,30 @@ process_server_config_line_depth(ServerOptions *options, char *line, options->per_source_penalty.enabled == -1) options->per_source_penalty.enabled = value2; continue; - } else if (strncmp(arg, "crash:", 6) == 0) { - p = arg + 6; - intptr = &options->per_source_penalty.penalty_crash; - } else if (strncmp(arg, "authfail:", 9) == 0) { - p = arg + 9; - intptr = &options->per_source_penalty.penalty_authfail; - } else if (strncmp(arg, "noauth:", 7) == 0) { - p = arg + 7; - intptr = &options->per_source_penalty.penalty_noauth; - } else if (strncmp(arg, "grace-exceeded:", 15) == 0) { - p = arg + 15; - intptr = &options->per_source_penalty.penalty_grace; - } else if (strncmp(arg, "refuseconnection:", 17) == 0) { - p = arg + 17; - intptr = &options->per_source_penalty.penalty_refuseconnection; - } else if (strncmp(arg, "max:", 4) == 0) { - p = arg + 4; - intptr = &options->per_source_penalty.penalty_max; - } else if (strncmp(arg, "min:", 4) == 0) { - p = arg + 4; - intptr = &options->per_source_penalty.penalty_min; - } else if (strncmp(arg, "max-sources4:", 13) == 0) { + } else if ((q = strprefix(arg, "crash:", 0)) != NULL) { + doubleptr = &options->per_source_penalty.penalty_crash; + } else if ((q = strprefix(arg, "authfail:", 0)) != NULL) { + doubleptr = &options->per_source_penalty.penalty_authfail; + } else if ((q = strprefix(arg, "invaliduser:", 0)) != NULL) { + doubleptr = &options->per_source_penalty.penalty_invaliduser; + } else if ((q = strprefix(arg, "noauth:", 0)) != NULL) { + doubleptr = &options->per_source_penalty.penalty_noauth; + } else if ((q = strprefix(arg, "grace-exceeded:", 0)) != NULL) { + doubleptr = &options->per_source_penalty.penalty_grace; + } else if ((q = strprefix(arg, "refuseconnection:", 0)) != NULL) { + doubleptr = &options->per_source_penalty.penalty_refuseconnection; + } else if ((q = strprefix(arg, "max:", 0)) != NULL) { + doubleptr = &options->per_source_penalty.penalty_max; + } else if ((q = strprefix(arg, "min:", 0)) != NULL) { + doubleptr = &options->per_source_penalty.penalty_min; + } else if ((q = strprefix(arg, "max-sources4:", 0)) != NULL) { intptr = &options->per_source_penalty.max_sources4; - if ((errstr = atoi_err(arg+13, &value)) != NULL) + if ((errstr = atoi_err(q, &value)) != NULL) fatal("%s line %d: %s value %s.", filename, linenum, keyword, errstr); - } else if (strncmp(arg, "max-sources6:", 13) == 0) { + } else if ((q = strprefix(arg, "max-sources6:", 0)) != NULL) { intptr = &options->per_source_penalty.max_sources6; - if ((errstr = atoi_err(arg+13, &value)) != NULL) + if ((errstr = atoi_err(q, &value)) != NULL) fatal("%s line %d: %s value %s.", filename, linenum, keyword, errstr); } else if (strcmp(arg, "overflow:deny-all") == 0) { @@ -2132,15 +2148,24 @@ process_server_config_line_depth(ServerOptions *options, char *line, fatal("%s line %d: unsupported %s keyword %s", filename, linenum, keyword, arg); } - /* If no value was parsed above, assume it's a time */ - if (value == -1 && (value = convtime(p)) == -1) { - fatal("%s line %d: invalid %s time value.", - filename, linenum, keyword); - } - if (*activep && *intptr == -1) { - *intptr = value; - /* any option implicitly enables penalties */ - options->per_source_penalty.enabled = 1; + + if (doubleptr != NULL) { + if ((dvalue = convtime_double(q)) < 0) { + fatal("%s line %d: invalid %s time value.", + filename, linenum, keyword); + } + if (*activep && *doubleptr < 0.0) { + *doubleptr = dvalue; + options->per_source_penalty.enabled = 1; + } + } else if (intptr != NULL) { + if (*activep && *intptr == -1) { + *intptr = value; + options->per_source_penalty.enabled = 1; + } + } else { + fatal_f("%s line %d: internal error", + filename, linenum); } } if (!found) { @@ -2168,13 +2193,25 @@ process_server_config_line_depth(ServerOptions *options, char *line, * AuthorizedKeysFile /etc/ssh_keys/%u */ case sAuthorizedKeysFile: - found = options->num_authkeys_files == 0; + uintptr = &options->num_authkeys_files; + chararrayptr = &options->authorized_keys_files; + parse_filenames: + found = *uintptr == 0; while ((arg = argv_next(&ac, &av)) != NULL) { if (*arg == '\0') { error("%s line %d: keyword %s empty argument", filename, linenum, keyword); goto out; } + /* Allow "none" only in first position */ + if (strcasecmp(arg, "none") == 0) { + if (nstrs > 0 || ac > 0) { + error("%s line %d: keyword %s \"none\" " + "argument must appear alone.", + filename, linenum, keyword); + goto out; + } + } arg2 = tilde_expand_filename(arg, getuid()); opt_array_append(filename, linenum, keyword, &strs, &nstrs, arg2); @@ -2185,8 +2222,8 @@ process_server_config_line_depth(ServerOptions *options, char *line, filename, linenum, keyword); } if (found && *activep) { - options->authorized_keys_files = strs; - options->num_authkeys_files = nstrs; + *chararrayptr = strs; + *uintptr = nstrs; strs = NULL; /* transferred */ nstrs = 0; } @@ -2477,8 +2514,9 @@ process_server_config_line_depth(ServerOptions *options, char *line, goto parse_filename; case sRevokedKeys: - charptr = &options->revoked_keys_file; - goto parse_filename; + uintptr = &options->num_revoked_keys_files; + chararrayptr = &options->revoked_keys_files; + goto parse_filenames; case sSecurityKeyProvider: charptr = &options->sk_provider; @@ -2503,13 +2541,25 @@ process_server_config_line_depth(ServerOptions *options, char *line, if ((value = parse_ipqos(arg)) == -1) fatal("%s line %d: Bad %s value: %s", filename, linenum, keyword, arg); + if (value == INT_MIN) { + debug("%s line %d: Deprecated IPQoS value \"%s\" " + "ignored - using system default instead. Consider" + " using DSCP values.", filename, linenum, arg); + value = INT_MAX; + } arg = argv_next(&ac, &av); if (arg == NULL) value2 = value; else if ((value2 = parse_ipqos(arg)) == -1) fatal("%s line %d: Bad %s value: %s", filename, linenum, keyword, arg); - if (*activep) { + if (value2 == INT_MIN) { + debug("%s line %d: Deprecated IPQoS value \"%s\" " + "ignored - using system default instead. Consider" + " using DSCP values.", filename, linenum, arg); + value2 = INT_MAX; + } + if (*activep && options->ip_qos_interactive == -1) { options->ip_qos_interactive = value; options->ip_qos_bulk = value2; } @@ -2705,6 +2755,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, charptr = &options->sshd_session_path; goto parse_filename; + case sSshdAuthPath: + charptr = &options->sshd_auth_path; + goto parse_filename; + case sRefuseConnection: intptr = &options->refuse_connection; multistate_ptr = multistate_flag; @@ -2802,23 +2856,25 @@ parse_server_match_config(ServerOptions *options, copy_set_server_options(options, &mo, 0); } -int parse_server_match_testspec(struct connection_info *ci, char *spec) +int +parse_server_match_testspec(struct connection_info *ci, char *spec) { char *p; + const char *val; while ((p = strsep(&spec, ",")) && *p != '\0') { - if (strncmp(p, "addr=", 5) == 0) { - ci->address = xstrdup(p + 5); - } else if (strncmp(p, "host=", 5) == 0) { - ci->host = xstrdup(p + 5); - } else if (strncmp(p, "user=", 5) == 0) { - ci->user = xstrdup(p + 5); - } else if (strncmp(p, "laddr=", 6) == 0) { - ci->laddress = xstrdup(p + 6); - } else if (strncmp(p, "rdomain=", 8) == 0) { - ci->rdomain = xstrdup(p + 8); - } else if (strncmp(p, "lport=", 6) == 0) { - ci->lport = a2port(p + 6); + if ((val = strprefix(p, "addr=", 0)) != NULL) { + ci->address = xstrdup(val); + } else if ((val = strprefix(p, "host=", 0)) != NULL) { + ci->host = xstrdup(val); + } else if ((val = strprefix(p, "user=", 0)) != NULL) { + ci->user = xstrdup(val); + } else if ((val = strprefix(p, "laddr=", 0)) != NULL) { + ci->laddress = xstrdup(val); + } else if ((val = strprefix(p, "rdomain=", 0)) != NULL) { + ci->rdomain = xstrdup(val); + } else if ((val = strprefix(p, "lport=", 0)) != NULL) { + ci->lport = a2port(val); if (ci->lport == -1) { fprintf(stderr, "Invalid port '%s' in test mode" " specification %s\n", p+6, p); @@ -2943,10 +2999,10 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) #define M_CP_STROPT(n) do {\ if (src->n != NULL && dst->n != src->n) { \ free(dst->n); \ - dst->n = src->n; \ + dst->n = xstrdup(src->n); \ } \ } while(0) -#define M_CP_STRARRAYOPT(s, num_s) do {\ +#define M_CP_STRARRAYOPT(s, num_s, clobber) do {\ u_int i; \ if (src->num_s != 0) { \ for (i = 0; i < dst->num_s; i++) \ @@ -2955,7 +3011,8 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) dst->s = xcalloc(src->num_s, sizeof(*dst->s)); \ for (i = 0; i < src->num_s; i++) \ dst->s[i] = xstrdup(src->s[i]); \ - dst->num_s = src->num_s; \ + if (clobber) \ + dst->num_s = src->num_s; \ } \ } while(0) @@ -3233,6 +3290,8 @@ dump_config(ServerOptions *o) #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); + dump_cfg_fmtint(sGssDelegateCreds, o->gss_deleg_creds); + dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor); #endif dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); dump_cfg_fmtint(sKbdInteractiveAuthentication, @@ -3270,7 +3329,6 @@ dump_config(ServerOptions *o) dump_cfg_string(sForceCommand, o->adm_forced_command); dump_cfg_string(sChrootDirectory, o->chroot_directory); dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys); - dump_cfg_string(sRevokedKeys, o->revoked_keys_file); dump_cfg_string(sSecurityKeyProvider, o->sk_provider); dump_cfg_string(sAuthorizedPrincipalsFile, o->authorized_principals_file); @@ -3290,6 +3348,7 @@ dump_config(ServerOptions *o) dump_cfg_string(sRDomain, o->routing_domain); #endif dump_cfg_string(sSshdSessionPath, o->sshd_session_path); + dump_cfg_string(sSshdAuthPath, o->sshd_auth_path); dump_cfg_string(sPerSourcePenaltyExemptList, o->per_source_penalty_exempt); /* string arguments requiring a lookup */ @@ -3299,6 +3358,8 @@ dump_config(ServerOptions *o) /* string array arguments */ dump_cfg_strarray_oneline(sAuthorizedKeysFile, o->num_authkeys_files, o->authorized_keys_files); + dump_cfg_strarray_oneline(sRevokedKeys, o->num_revoked_keys_files, + o->revoked_keys_files); dump_cfg_strarray(sHostKeyFile, o->num_host_key_files, o->host_key_files); dump_cfg_strarray(sHostCertificate, o->num_host_cert_files, @@ -3380,13 +3441,15 @@ dump_config(ServerOptions *o) printf("\n"); if (o->per_source_penalty.enabled) { - printf("persourcepenalties crash:%d authfail:%d noauth:%d " - "grace-exceeded:%d refuseconnection:%d max:%d min:%d " + printf("persourcepenalties crash:%f authfail:%f noauth:%f " + "invaliduser:%f " + "grace-exceeded:%f refuseconnection:%f max:%f min:%f " "max-sources4:%d max-sources6:%d " "overflow:%s overflow6:%s\n", o->per_source_penalty.penalty_crash, o->per_source_penalty.penalty_authfail, o->per_source_penalty.penalty_noauth, + o->per_source_penalty.penalty_invaliduser, o->per_source_penalty.penalty_grace, o->per_source_penalty.penalty_refuseconnection, o->per_source_penalty.penalty_max, diff --git a/servconf.h b/servconf.h index 5089bc9..b06db09 100644 --- a/servconf.h +++ b/servconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.h,v 1.168 2024/09/15 01:18:26 djm Exp $ */ +/* $OpenBSD: servconf.h,v 1.176 2026/03/03 09:57:25 dtucker Exp $ */ /* * Author: Tatu Ylonen @@ -16,7 +16,7 @@ #ifndef SERVCONF_H #define SERVCONF_H -#include +#include #define MAX_PORTS 256 /* Max # ports. */ @@ -73,13 +73,14 @@ struct per_source_penalty { int max_sources6; int overflow_mode; int overflow_mode6; - int penalty_crash; - int penalty_grace; - int penalty_authfail; - int penalty_noauth; - int penalty_refuseconnection; - int penalty_max; - int penalty_min; + double penalty_crash; + double penalty_grace; + double penalty_authfail; + double penalty_invaliduser; + double penalty_noauth; + double penalty_refuseconnection; + double penalty_max; + double penalty_min; }; typedef struct { @@ -151,6 +152,7 @@ typedef struct { * authenticated with Kerberos. */ int gss_authentication; /* If true, permit GSSAPI authentication */ int gss_cleanup_creds; /* If true, destroy cred cache on logout */ + int gss_deleg_creds; /* If true, accept delegated GSS credentials */ int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */ int password_authentication; /* If true, permit password * authentication. */ @@ -221,7 +223,8 @@ typedef struct { u_int num_permitted_listens; char *chroot_directory; - char *revoked_keys_file; + uint num_revoked_keys_files; + char **revoked_keys_files; char *trusted_user_ca_keys; char *authorized_keys_command; char *authorized_keys_command_user; @@ -239,7 +242,7 @@ typedef struct { int fingerprint_hash; int expose_userauth_info; - u_int64_t timing_secret; + uint64_t timing_secret; char *sk_provider; int required_rsa_size; /* minimum size of RSA keys */ @@ -249,6 +252,7 @@ typedef struct { int unused_connection_timeout; char *sshd_session_path; + char *sshd_auth_path; int refuse_connection; } ServerOptions; @@ -288,7 +292,6 @@ TAILQ_HEAD(include_list, include_item); #define COPY_MATCH_STRING_OPTS() do { \ M_CP_STROPT(banner); \ M_CP_STROPT(trusted_user_ca_keys); \ - M_CP_STROPT(revoked_keys_file); \ M_CP_STROPT(authorized_keys_command); \ M_CP_STROPT(authorized_keys_command_user); \ M_CP_STROPT(authorized_principals_file); \ @@ -300,21 +303,24 @@ TAILQ_HEAD(include_list, include_item); M_CP_STROPT(routing_domain); \ M_CP_STROPT(permit_user_env_allowlist); \ M_CP_STROPT(pam_service_name); \ - M_CP_STRARRAYOPT(authorized_keys_files, num_authkeys_files); \ - M_CP_STRARRAYOPT(allow_users, num_allow_users); \ - M_CP_STRARRAYOPT(deny_users, num_deny_users); \ - M_CP_STRARRAYOPT(allow_groups, num_allow_groups); \ - M_CP_STRARRAYOPT(deny_groups, num_deny_groups); \ - M_CP_STRARRAYOPT(accept_env, num_accept_env); \ - M_CP_STRARRAYOPT(setenv, num_setenv); \ - M_CP_STRARRAYOPT(auth_methods, num_auth_methods); \ - M_CP_STRARRAYOPT(permitted_opens, num_permitted_opens); \ - M_CP_STRARRAYOPT(permitted_listens, num_permitted_listens); \ - M_CP_STRARRAYOPT(channel_timeouts, num_channel_timeouts); \ - M_CP_STRARRAYOPT(log_verbose, num_log_verbose); \ - M_CP_STRARRAYOPT(subsystem_name, num_subsystems); \ - M_CP_STRARRAYOPT(subsystem_command, num_subsystems); \ - M_CP_STRARRAYOPT(subsystem_args, num_subsystems); \ + M_CP_STRARRAYOPT(authorized_keys_files, num_authkeys_files, 1);\ + M_CP_STRARRAYOPT(revoked_keys_files, \ + num_revoked_keys_files, 1); \ + M_CP_STRARRAYOPT(allow_users, num_allow_users, 1); \ + M_CP_STRARRAYOPT(deny_users, num_deny_users, 1); \ + M_CP_STRARRAYOPT(allow_groups, num_allow_groups, 1); \ + M_CP_STRARRAYOPT(deny_groups, num_deny_groups, 1); \ + M_CP_STRARRAYOPT(accept_env, num_accept_env, 1); \ + M_CP_STRARRAYOPT(setenv, num_setenv, 1); \ + M_CP_STRARRAYOPT(auth_methods, num_auth_methods, 1); \ + M_CP_STRARRAYOPT(permitted_opens, num_permitted_opens, 1); \ + M_CP_STRARRAYOPT(permitted_listens, num_permitted_listens, 1); \ + M_CP_STRARRAYOPT(channel_timeouts, num_channel_timeouts, 1); \ + M_CP_STRARRAYOPT(log_verbose, num_log_verbose, 1); \ + /* Note: don't clobber num_subsystems until all copied */ \ + M_CP_STRARRAYOPT(subsystem_name, num_subsystems, 0); \ + M_CP_STRARRAYOPT(subsystem_command, num_subsystems, 0); \ + M_CP_STRARRAYOPT(subsystem_args, num_subsystems, 1); \ } while (0) void initialize_server_options(ServerOptions *); diff --git a/serverloop.c b/serverloop.c index 757cc6f..8e63480 100644 --- a/serverloop.c +++ b/serverloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: serverloop.c,v 1.240 2024/06/17 08:28:31 djm Exp $ */ +/* $OpenBSD: serverloop.c,v 1.246 2026/03/03 09:57:25 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -40,9 +40,8 @@ #include #include #include -#ifdef HAVE_SYS_TIME_H -# include -#endif +#include +#include #include @@ -50,16 +49,13 @@ #include #include #include -#ifdef HAVE_POLL_H #include -#endif #include #include #include #include #include -#include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "packet.h" #include "sshbuf.h" @@ -89,7 +85,8 @@ extern struct sshauthopt *auth_opts; static int no_more_sessions = 0; /* Disallow further sessions. */ -static volatile sig_atomic_t child_terminated = 0; /* The child has terminated. */ +static volatile sig_atomic_t child_terminated = 0; /* set on SIGCHLD */ +static volatile sig_atomic_t siginfo_received = 0; /* prototypes */ static void server_init_dispatch(struct ssh *); @@ -103,6 +100,14 @@ sigchld_handler(int sig) child_terminated = 1; } +#ifdef SIGINFO +static void +siginfo_handler(int sig) +{ + siginfo_received = 1; +} +#endif + static void client_alive_check(struct ssh *ssh) { @@ -173,12 +178,15 @@ wait_until_can_do_something(struct ssh *ssh, * start the clock to terminate the connection. */ if (options.unused_connection_timeout != 0) { - if (channel_still_open(ssh) || unused_connection_expiry == 0) { + if (channel_still_open(ssh)) + unused_connection_expiry = 0; + else if (unused_connection_expiry == 0) { unused_connection_expiry = now + options.unused_connection_timeout; } - ptimeout_deadline_monotime(&timeout, unused_connection_expiry); } + if (unused_connection_expiry != 0) + ptimeout_deadline_monotime(&timeout, unused_connection_expiry); /* * if using client_alive, set the max timeout accordingly, @@ -285,8 +293,15 @@ static void process_output(struct ssh *ssh, int connection_out) { int r; + static int interactive = -1; /* Send any buffered packet data to the client. */ + if (interactive != !channel_has_bulk(ssh)) { + interactive = !channel_has_bulk(ssh); + debug2_f("session QoS is now %s", interactive ? + "interactive" : "non-interactive"); + ssh_packet_set_interactive(ssh, interactive); + } if ((r = ssh_packet_write_poll(ssh)) != 0) { sshpkt_fatal(ssh, r, "%s: ssh_packet_write_poll", __func__); @@ -326,9 +341,15 @@ server_loop2(struct ssh *ssh, Authctxt *authctxt) debug("Entering interactive session for SSH2."); - if (sigemptyset(&bsigset) == -1 || sigaddset(&bsigset, SIGCHLD) == -1) + if (sigemptyset(&bsigset) == -1 || + sigaddset(&bsigset, SIGCHLD) == -1) error_f("bsigset setup: %s", strerror(errno)); ssh_signal(SIGCHLD, sigchld_handler); +#ifdef SIGINFO + if (sigaddset(&bsigset, SIGINFO) == -1) + error_f("bsigset setup: %s", strerror(errno)); + ssh_signal(SIGINFO, siginfo_handler); +#endif child_terminated = 0; connection_in = ssh_packet_get_connection_in(ssh); connection_out = ssh_packet_get_connection_out(ssh); @@ -350,6 +371,10 @@ server_loop2(struct ssh *ssh, Authctxt *authctxt) if (sigprocmask(SIG_BLOCK, &bsigset, &osigset) == -1) error_f("bsigset sigprocmask: %s", strerror(errno)); collect_children(ssh); + if (siginfo_received) { + siginfo_received = 0; + channel_report_open(ssh, SYSLOG_LEVEL_INFO); + } wait_until_can_do_something(ssh, connection_in, connection_out, &pfd, &npfd_alloc, &npfd_active, &osigset, &conn_in_ready, &conn_out_ready); @@ -377,7 +402,7 @@ server_loop2(struct ssh *ssh, Authctxt *authctxt) } static int -server_input_keep_alive(int type, u_int32_t seq, struct ssh *ssh) +server_input_keep_alive(int type, uint32_t seq, struct ssh *ssh) { debug("Got %d/%u for keepalive", type, seq); /* @@ -583,7 +608,7 @@ server_request_session(struct ssh *ssh) } static int -server_input_channel_open(int type, u_int32_t seq, struct ssh *ssh) +server_input_channel_open(int type, uint32_t seq, struct ssh *ssh) { Channel *c = NULL; char *ctype = NULL; @@ -650,7 +675,7 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp) int r, ndx, success = 0; const u_char *blob; const char *sigalg, *kex_rsa_sigalg = NULL; - u_char *sig = 0; + u_char *sig = NULL; size_t blen, slen; if ((resp = sshbuf_new()) == NULL || (sigbuf = sshbuf_new()) == NULL) @@ -690,7 +715,7 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp) * For RSA keys, prefer to use the signature type negotiated * during KEX to the default (SHA1). */ - sigalg = NULL; + sigalg = sshkey_ssh_name(key); if (sshkey_type_plain(key->type) == KEY_RSA) { if (kex_rsa_sigalg != NULL) sigalg = kex_rsa_sigalg; @@ -699,6 +724,7 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp) else if (ssh->kex->flags & KEX_RSA_SHA2_256_SUPPORTED) sigalg = "rsa-sha2-256"; } + debug3_f("sign %s key (index %d) using sigalg %s", sshkey_type(key), ndx, sigalg == NULL ? "default" : sigalg); if ((r = sshbuf_put_cstring(sigbuf, @@ -726,7 +752,7 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp) } static int -server_input_global_request(int type, u_int32_t seq, struct ssh *ssh) +server_input_global_request(int type, uint32_t seq, struct ssh *ssh) { char *rtype = NULL; u_char want_reply = 0; @@ -831,7 +857,7 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh) } static int -server_input_channel_req(int type, u_int32_t seq, struct ssh *ssh) +server_input_channel_req(int type, uint32_t seq, struct ssh *ssh) { Channel *c; int r, success = 0; diff --git a/session.c b/session.c index c941511..93de35d 100644 --- a/session.c +++ b/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.338 2024/05/17 00:30:24 djm Exp $ */ +/* $OpenBSD: session.c,v 1.348 2026/03/05 05:40:36 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -36,12 +36,11 @@ #include "includes.h" #include -#ifdef HAVE_SYS_STAT_H -# include -#endif -#include -#include #include +#include +#include +#include +#include #include @@ -50,9 +49,7 @@ #include #include #include -#ifdef HAVE_PATHS_H #include -#endif #include #include #include @@ -62,7 +59,6 @@ #include #include -#include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "ssh.h" #include "ssh2.h" @@ -75,9 +71,7 @@ #include "channels.h" #include "sshkey.h" #include "cipher.h" -#ifdef GSSAPI -#include "ssh-gss.h" -#endif +#include "kex.h" #include "hostfile.h" #include "auth.h" #include "auth-options.h" @@ -90,7 +84,9 @@ #include "serverloop.h" #include "canohost.h" #include "session.h" -#include "kex.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif #include "monitor_wrap.h" #include "sftp.h" #include "atomicio.h" @@ -143,9 +139,6 @@ static int session_pty_req(struct ssh *, Session *); extern ServerOptions options; extern char *__progname; extern int debug_flag; -extern u_int utmp_len; -extern int startup_pipe; -extern void destroy_sensitive_data(void); extern struct sshbuf *loginmsg; extern struct sshauthopt *auth_opts; extern char *tun_fwd_ifnames; /* serverloop.c */ @@ -175,7 +168,6 @@ static char *auth_info_file = NULL; /* Name and directory of socket for authentication agent forwarding. */ static char *auth_sock_name = NULL; -static char *auth_sock_dir = NULL; /* removes the agent forwarding socket */ @@ -185,14 +177,13 @@ auth_sock_cleanup_proc(struct passwd *pw) if (auth_sock_name != NULL) { temporarily_use_uid(pw); unlink(auth_sock_name); - rmdir(auth_sock_dir); auth_sock_name = NULL; restore_uid(); } } static int -auth_input_request_forwarding(struct ssh *ssh, struct passwd * pw) +auth_input_request_forwarding(struct ssh *ssh, struct passwd *pw, int agent_new) { Channel *nc; int sock = -1; @@ -205,52 +196,29 @@ auth_input_request_forwarding(struct ssh *ssh, struct passwd * pw) /* Temporarily drop privileged uid for mkdir/bind. */ temporarily_use_uid(pw); - /* Allocate a buffer for the socket name, and format the name. */ - auth_sock_dir = xstrdup("/tmp/ssh-XXXXXXXXXX"); - - /* Create private directory for socket */ - if (mkdtemp(auth_sock_dir) == NULL) { + if (agent_listener(pw->pw_dir, "sshd", &sock, &auth_sock_name) != 0) { + /* a more detailed error is already logged */ ssh_packet_send_debug(ssh, "Agent forwarding disabled: " - "mkdtemp() failed: %.100s", strerror(errno)); + "couldn't create listener socket"); restore_uid(); - free(auth_sock_dir); - auth_sock_dir = NULL; goto authsock_err; } - - xasprintf(&auth_sock_name, "%s/agent.%ld", - auth_sock_dir, (long) getpid()); - - /* Start a Unix listener on auth_sock_name. */ - sock = unix_listener(auth_sock_name, SSH_LISTEN_BACKLOG, 0); - - /* Restore the privileged uid. */ restore_uid(); - /* Check for socket/bind/listen failure. */ - if (sock < 0) - goto authsock_err; - /* Allocate a channel for the authentication agent socket. */ nc = channel_new(ssh, "auth-listener", SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1, CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "auth socket", 1); nc->path = xstrdup(auth_sock_name); + nc->agent_new = agent_new; return 1; authsock_err: free(auth_sock_name); - if (auth_sock_dir != NULL) { - temporarily_use_uid(pw); - rmdir(auth_sock_dir); - restore_uid(); - free(auth_sock_dir); - } if (sock != -1) close(sock); auth_sock_name = NULL; - auth_sock_dir = NULL; return 0; } @@ -347,7 +315,7 @@ do_authenticated(struct ssh *ssh, Authctxt *authctxt) auth_log_authopts("active", auth_opts, 0); - /* setup the channel layer */ + /* set up the channel layer */ /* XXX - streamlocal? */ set_fwdpermit_from_authopts(ssh, auth_opts); @@ -524,9 +492,6 @@ do_exec_no_pty(struct ssh *ssh, Session *s, const char *command) #endif s->pid = pid; - /* Set interactive/non-interactive mode. */ - ssh_packet_set_interactive(ssh, s->display != NULL, - options.ip_qos_interactive, options.ip_qos_bulk); /* * Clear loginmsg, since it's the child's responsibility to display @@ -654,8 +619,6 @@ do_exec_pty(struct ssh *ssh, Session *s, const char *command) /* Enter interactive session. */ s->ptymaster = ptymaster; - ssh_packet_set_interactive(ssh, 1, - options.ip_qos_interactive, options.ip_qos_bulk); session_set_fds(ssh, s, ptyfd, fdout, -1, 1, 1); return 0; } @@ -1050,6 +1013,12 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell) if (getenv("TZ")) child_set_env(&env, &envsize, "TZ", getenv("TZ")); +#ifdef HAVE_LOGIN_CAP + if (getenv("XDG_RUNTIME_DIR")) { + child_set_env(&env, &envsize, "XDG_RUNTIME_DIR", + getenv("XDG_RUNTIME_DIR")); + } +#endif /* HAVE_LOGIN_CAP */ if (s->term) child_set_env(&env, &envsize, "TERM", s->term); if (s->display) @@ -1433,7 +1402,7 @@ do_pwchange(Session *s) fprintf(stderr, "WARNING: Your password has expired.\n"); if (s->ttyfd != -1) { fprintf(stderr, - "You must change your password now and login again!\n"); + "You must change your password now and log in again!\n"); #ifdef WITH_SELINUX setexeccon(NULL); #endif @@ -1510,8 +1479,7 @@ do_child(struct ssh *ssh, Session *s, const char *command) sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); - /* remove hostkey from the child's memory */ - destroy_sensitive_data(); + /* remove keys from memory */ ssh_packet_clear_keys(ssh); /* Force a password change */ @@ -2145,10 +2113,6 @@ session_signal_req(struct ssh *ssh, Session *s) signame, s->forced ? "forced-command" : "subsystem"); goto out; } - if (mm_is_monitor()) { - error_f("session signalling requires privilege separation"); - goto out; - } debug_f("signal %s, killpg(%ld, %d)", signame, (long)s->pid, sig); temporarily_use_uid(s->pw); @@ -2168,7 +2132,7 @@ session_signal_req(struct ssh *ssh, Session *s) } static int -session_auth_agent_req(struct ssh *ssh, Session *s) +session_auth_agent_req(struct ssh *ssh, Session *s, int agent_new) { static int called = 0; int r; @@ -2176,16 +2140,16 @@ session_auth_agent_req(struct ssh *ssh, Session *s) if ((r = sshpkt_get_end(ssh)) != 0) sshpkt_fatal(ssh, r, "%s: parse packet", __func__); if (!auth_opts->permit_agent_forwarding_flag || - !options.allow_agent_forwarding) { + !options.allow_agent_forwarding || + options.disable_forwarding) { debug_f("agent forwarding disabled"); return 0; } - if (called) { + if (called) return 0; - } else { - called = 1; - return auth_input_request_forwarding(ssh, s->pw); - } + + called = 1; + return auth_input_request_forwarding(ssh, s->pw, agent_new); } int @@ -2214,7 +2178,9 @@ session_input_channel_req(struct ssh *ssh, Channel *c, const char *rtype) } else if (strcmp(rtype, "x11-req") == 0) { success = session_x11_req(ssh, s); } else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) { - success = session_auth_agent_req(ssh, s); + success = session_auth_agent_req(ssh, s, 0); + } else if (strcmp(rtype, "agent-req") == 0) { + success = session_auth_agent_req(ssh, s, 1); } else if (strcmp(rtype, "subsystem") == 0) { success = session_subsystem_req(ssh, s); } else if (strcmp(rtype, "env") == 0) { @@ -2571,7 +2537,7 @@ session_setup_x11fwd(struct ssh *ssh, Session *s) ssh_packet_send_debug(ssh, "X11 forwarding disabled by key options."); return 0; } - if (!options.x11_forwarding) { + if (!options.x11_forwarding || options.disable_forwarding) { debug("X11 forwarding disabled in server configuration file."); return 0; } diff --git a/sftp-client.c b/sftp-client.c index be40d20..69ef28c 100644 --- a/sftp-client.c +++ b/sftp-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-client.c,v 1.176 2024/05/17 02:39:11 jsg Exp $ */ +/* $OpenBSD: sftp-client.c,v 1.185 2026/03/03 09:57:25 dtucker Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -23,28 +23,16 @@ #include "includes.h" #include -#ifdef HAVE_SYS_STATVFS_H +#include +#include +#include #include -#endif -#include "openbsd-compat/sys-queue.h" -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef HAVE_SYS_TIME_H -# include -#endif #include #include #include -#ifdef HAVE_POLL_H -#include -#else -# ifdef HAVE_SYS_POLL_H -# include -# endif -#endif #include +#include #include #include #include @@ -106,7 +94,7 @@ struct sftp_conn { #define SFTP_EXT_COPY_DATA 0x00000100 #define SFTP_EXT_GETUSERSGROUPS_BY_ID 0x00000200 u_int exts; - u_int64_t limit_kbps; + uint64_t limit_kbps; struct bwlimit bwlimit_in, bwlimit_out; }; @@ -114,7 +102,7 @@ struct sftp_conn { struct request { u_int id; size_t len; - u_int64_t offset; + uint64_t offset; TAILQ_ENTRY(request) tq; }; TAILQ_HEAD(requests, request); @@ -400,7 +388,7 @@ get_decode_statvfs(struct sftp_conn *conn, struct sftp_statvfs *st, struct sshbuf *msg; u_char type; u_int id; - u_int64_t flag; + uint64_t flag; int r; if ((msg = sshbuf_new()) == NULL) @@ -454,7 +442,7 @@ get_decode_statvfs(struct sftp_conn *conn, struct sftp_statvfs *st, struct sftp_conn * sftp_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests, - u_int64_t limit_kbps) + uint64_t limit_kbps) { u_char type; struct sshbuf *msg; @@ -581,17 +569,6 @@ sftp_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests, (unsigned long long)limits.read_length, ret->upload_buflen, ret->download_buflen); } - - /* Use the server limit to scale down our value only */ - if (num_requests == 0 && limits.open_handles) { - ret->num_requests = - MINIMUM(DEFAULT_NUM_REQUESTS, limits.open_handles); - if (ret->num_requests == 0) - ret->num_requests = 1; - debug3("server handle limit %llu; using %u", - (unsigned long long)limits.open_handles, - ret->num_requests); - } } /* Some filexfer v.0 servers don't support large packets */ @@ -611,6 +588,14 @@ sftp_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests, return ret; } +void +sftp_free(struct sftp_conn *conn) +{ + if (conn == NULL) + return; + freezero(conn, sizeof(*conn)); +} + u_int sftp_proto_version(struct sftp_conn *conn) { @@ -1138,7 +1123,7 @@ sftp_copy(struct sftp_conn *conn, const char *oldpath, const char *newpath) attr.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; if ((msg = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); attrib_clear(&junk); /* Send empty attributes */ @@ -1149,7 +1134,7 @@ sftp_copy(struct sftp_conn *conn, const char *oldpath, const char *newpath) (r = sshbuf_put_cstring(msg, oldpath)) != 0 || (r = sshbuf_put_u32(msg, SSH2_FXF_READ)) != 0 || (r = encode_attrib(msg, &junk)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); send_msg(conn, msg); debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, oldpath); @@ -1170,7 +1155,7 @@ sftp_copy(struct sftp_conn *conn, const char *oldpath, const char *newpath) (r = sshbuf_put_u32(msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT| SSH2_FXF_TRUNC)) != 0 || (r = encode_attrib(msg, &attr)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); send_msg(conn, msg); debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, newpath); @@ -1194,7 +1179,7 @@ sftp_copy(struct sftp_conn *conn, const char *oldpath, const char *newpath) (r = sshbuf_put_u64(msg, 0)) != 0 || (r = sshbuf_put_string(msg, new_handle, new_handle_len)) != 0 || (r = sshbuf_put_u64(msg, 0)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); send_msg(conn, msg); debug3("Sent message copy-data \"%s\" 0 0 -> \"%s\" 0", oldpath, newpath); @@ -1519,7 +1504,7 @@ sftp_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a) } static void -send_read_request(struct sftp_conn *conn, u_int id, u_int64_t offset, +send_read_request(struct sftp_conn *conn, u_int id, uint64_t offset, u_int len, const u_char *handle, u_int handle_len) { struct sshbuf *msg; @@ -1602,7 +1587,7 @@ sftp_download(struct sftp_conn *conn, const char *remote_path, u_char *handle; int local_fd = -1, write_error; int read_error, write_errno, lmodified = 0, reordered = 0, r; - u_int64_t offset = 0, size, highwater = 0, maxack = 0; + uint64_t offset = 0, size, highwater = 0, maxack = 0; u_int mode, id, buflen, num_req, max_req, status = SSH2_FX_OK; off_t progress_counter; size_t handle_len; @@ -1663,7 +1648,7 @@ sftp_download(struct sftp_conn *conn, const char *remote_path, error("\"%s\" has negative size", local_path); goto fail; } - if ((u_int64_t)st.st_size > size) { + if ((uint64_t)st.st_size > size) { error("Unable to resume download of \"%s\": " "local file is larger than remote", local_path); fail: @@ -2034,14 +2019,14 @@ sftp_upload(struct sftp_conn *conn, const char *local_path, int fsync_flag, int inplace_flag) { int r, local_fd; - u_int openmode, id, status = SSH2_FX_OK, reordered = 0; + u_int openmode, id, status = SSH2_FX_OK, status2, reordered = 0; off_t offset, progress_counter; u_char type, *handle, *data; struct sshbuf *msg; struct stat sb; Attrib a, t, c; - u_int32_t startid, ackid; - u_int64_t highwater = 0, maxack = 0; + uint32_t startid, ackid; + uint64_t highwater = 0, maxack = 0; struct request *ack = NULL; struct requests acks; size_t handle_len; @@ -2091,6 +2076,7 @@ sftp_upload(struct sftp_conn *conn, const char *local_path, close(local_fd); return -1; } + highwater = c.size; } openmode = SSH2_FXF_WRITE|SSH2_FXF_CREAT; @@ -2171,9 +2157,11 @@ sftp_upload(struct sftp_conn *conn, const char *local_path, fatal("Expected SSH2_FXP_STATUS(%d) packet, " "got %d", SSH2_FXP_STATUS, type); - if ((r = sshbuf_get_u32(msg, &status)) != 0) + if ((r = sshbuf_get_u32(msg, &status2)) != 0) fatal_fr(r, "parse status"); - debug3("SSH2_FXP_STATUS %u", status); + debug3("SSH2_FXP_STATUS %u", status2); + if (status2 != SSH2_FX_OK) + status = status2; /* remember errors */ /* Find the request in our queue */ if ((ack = request_find(&acks, rid)) == NULL) @@ -2251,13 +2239,13 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, int depth, int preserve_flag, int print_flag, int resume, int fsync_flag, int follow_link_flag, int inplace_flag) { - int ret = 0; + int created = 0, ret = 0; DIR *dirp; struct dirent *dp; char *filename, *new_src = NULL, *new_dst = NULL; struct stat sb; Attrib a, dirattrib; - u_int32_t saved_perm; + uint32_t saved_perm; debug2_f("upload local dir \"%s\" to remote \"%s\"", src, dst); @@ -2292,7 +2280,9 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, */ saved_perm = a.perm; a.perm |= (S_IWUSR|S_IXUSR); - if (sftp_mkdir(conn, dst, &a, 0) != 0) { + if (sftp_mkdir(conn, dst, &a, 0) == 0) + created = 1; + else { if (sftp_stat(conn, dst, 0, &dirattrib) != 0) return -1; if (!S_ISDIR(dirattrib.perm)) { @@ -2356,7 +2346,8 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, free(new_dst); free(new_src); - sftp_setstat(conn, dst, &a); + if (created || preserve_flag) + sftp_setstat(conn, dst, &a); (void) closedir(dirp); return ret; @@ -2456,7 +2447,7 @@ sftp_crossload(struct sftp_conn *from, struct sftp_conn *to, { struct sshbuf *msg; int write_error, read_error, r; - u_int64_t offset = 0, size; + uint64_t offset = 0, size; u_int id, buflen, num_req, max_req, status = SSH2_FX_OK; u_int num_upload_req; off_t progress_counter; @@ -2702,7 +2693,7 @@ crossload_dir_internal(struct sftp_conn *from, struct sftp_conn *to, int depth, Attrib *dirattrib, int preserve_flag, int print_flag, int follow_link_flag) { - int i, ret = 0; + int i, ret = 0, created = 0; SFTP_DIRENT **dir_entries; char *filename, *new_from_path = NULL, *new_to_path = NULL; mode_t mode = 0777; @@ -2748,7 +2739,9 @@ crossload_dir_internal(struct sftp_conn *from, struct sftp_conn *to, * the path already existed and is a directory. Ensure we can * write to the directory we create for the duration of the transfer. */ - if (sftp_mkdir(to, to_path, &curdir, 0) != 0) { + if (sftp_mkdir(to, to_path, &curdir, 0) == 0) + created = 1; + else { if (sftp_stat(to, to_path, 0, &newdir) != 0) return -1; if (!S_ISDIR(newdir.perm)) { @@ -2810,7 +2803,8 @@ crossload_dir_internal(struct sftp_conn *from, struct sftp_conn *to, free(new_to_path); free(new_from_path); - sftp_setstat(to, to_path, &curdir); + if (created || preserve_flag) + sftp_setstat(to, to_path, &curdir); sftp_free_dirents(dir_entries); diff --git a/sftp-client.h b/sftp-client.h index 74cdae7..cc8e202 100644 --- a/sftp-client.h +++ b/sftp-client.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-client.h,v 1.39 2023/09/08 05:56:13 djm Exp $ */ +/* $OpenBSD: sftp-client.h,v 1.41 2026/03/03 09:57:25 dtucker Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller @@ -21,12 +21,6 @@ #ifndef _SFTP_CLIENT_H #define _SFTP_CLIENT_H -#ifdef USE_SYSTEM_GLOB -# include -#else -# include "openbsd-compat/glob.h" -#endif - typedef struct SFTP_DIRENT SFTP_DIRENT; struct SFTP_DIRENT { @@ -40,25 +34,25 @@ struct SFTP_DIRENT { * server's native format may be larger than the client's. */ struct sftp_statvfs { - u_int64_t f_bsize; - u_int64_t f_frsize; - u_int64_t f_blocks; - u_int64_t f_bfree; - u_int64_t f_bavail; - u_int64_t f_files; - u_int64_t f_ffree; - u_int64_t f_favail; - u_int64_t f_fsid; - u_int64_t f_flag; - u_int64_t f_namemax; + uint64_t f_bsize; + uint64_t f_frsize; + uint64_t f_blocks; + uint64_t f_bfree; + uint64_t f_bavail; + uint64_t f_files; + uint64_t f_ffree; + uint64_t f_favail; + uint64_t f_fsid; + uint64_t f_flag; + uint64_t f_namemax; }; /* Used for limits response on the wire from the server */ struct sftp_limits { - u_int64_t packet_length; - u_int64_t read_length; - u_int64_t write_length; - u_int64_t open_handles; + uint64_t packet_length; + uint64_t read_length; + uint64_t write_length; + uint64_t open_handles; }; /* print flag values */ @@ -70,7 +64,8 @@ struct sftp_limits { * Initialise a SSH filexfer connection. Returns NULL on error or * a pointer to a initialized sftp_conn struct on success. */ -struct sftp_conn *sftp_init(int, int, u_int, u_int, u_int64_t); +struct sftp_conn *sftp_init(int, int, u_int, u_int, uint64_t); +void sftp_free(struct sftp_conn *); u_int sftp_proto_version(struct sftp_conn *); diff --git a/sftp-common.c b/sftp-common.c index 5d72498..eb5cc2b 100644 --- a/sftp-common.c +++ b/sftp-common.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-common.c,v 1.34 2023/03/31 04:00:37 djm Exp $ */ +/* $OpenBSD: sftp-common.c,v 1.36 2026/02/11 17:05:32 dtucker Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2001 Damien Miller. All rights reserved. @@ -32,14 +32,12 @@ #include #include #include -#include #include -#include #include +#include +#include #include -#ifdef HAVE_UTIL_H #include -#endif #include "xmalloc.h" #include "ssherr.h" diff --git a/sftp-common.h b/sftp-common.h index 421a78f..95e90d4 100644 --- a/sftp-common.h +++ b/sftp-common.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-common.h,v 1.13 2022/09/19 10:41:58 djm Exp $ */ +/* $OpenBSD: sftp-common.h,v 1.14 2026/03/03 09:57:25 dtucker Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -33,13 +33,13 @@ typedef struct Attrib Attrib; /* File attributes */ struct Attrib { - u_int32_t flags; - u_int64_t size; - u_int32_t uid; - u_int32_t gid; - u_int32_t perm; - u_int32_t atime; - u_int32_t mtime; + uint32_t flags; + uint64_t size; + uint32_t uid; + uint32_t gid; + uint32_t perm; + uint32_t atime; + uint32_t mtime; }; void attrib_clear(Attrib *); diff --git a/sftp-glob.c b/sftp-glob.c index 1b82759..a8d3e07 100644 --- a/sftp-glob.c +++ b/sftp-glob.c @@ -18,11 +18,10 @@ #include "includes.h" #include -#ifdef HAVE_SYS_STAT_H -# include -#endif +#include #include +#include #include #include #include diff --git a/sftp-server.0 b/sftp-server.0 index f86aaf1..91e0cc4 100644 --- a/sftp-server.0 +++ b/sftp-server.0 @@ -95,4 +95,4 @@ HISTORY AUTHORS Markus Friedl -OpenBSD 7.6 July 27, 2021 OpenBSD 7.6 +OpenBSD 7.8 July 27, 2021 SFTP-SERVER(8) diff --git a/sftp-server.c b/sftp-server.c index a4abb9f..ebdb31d 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.148 2024/04/30 06:23:51 djm Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.153 2026/03/03 09:57:25 dtucker Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -18,24 +18,16 @@ #include "includes.h" #include -#include #include -#ifdef HAVE_SYS_TIME_H -# include -#endif -#ifdef HAVE_SYS_MOUNT_H -#include -#endif -#ifdef HAVE_SYS_STATVFS_H +#include +#include #include -#endif #include #include #include -#ifdef HAVE_POLL_H +#include #include -#endif #include #include #include @@ -95,42 +87,42 @@ struct Stat { }; /* Packet handlers */ -static void process_open(u_int32_t id); -static void process_close(u_int32_t id); -static void process_read(u_int32_t id); -static void process_write(u_int32_t id); -static void process_stat(u_int32_t id); -static void process_lstat(u_int32_t id); -static void process_fstat(u_int32_t id); -static void process_setstat(u_int32_t id); -static void process_fsetstat(u_int32_t id); -static void process_opendir(u_int32_t id); -static void process_readdir(u_int32_t id); -static void process_remove(u_int32_t id); -static void process_mkdir(u_int32_t id); -static void process_rmdir(u_int32_t id); -static void process_realpath(u_int32_t id); -static void process_rename(u_int32_t id); -static void process_readlink(u_int32_t id); -static void process_symlink(u_int32_t id); -static void process_extended_posix_rename(u_int32_t id); -static void process_extended_statvfs(u_int32_t id); -static void process_extended_fstatvfs(u_int32_t id); -static void process_extended_hardlink(u_int32_t id); -static void process_extended_fsync(u_int32_t id); -static void process_extended_lsetstat(u_int32_t id); -static void process_extended_limits(u_int32_t id); -static void process_extended_expand(u_int32_t id); -static void process_extended_copy_data(u_int32_t id); -static void process_extended_home_directory(u_int32_t id); -static void process_extended_get_users_groups_by_id(u_int32_t id); -static void process_extended(u_int32_t id); +static void process_open(uint32_t id); +static void process_close(uint32_t id); +static void process_read(uint32_t id); +static void process_write(uint32_t id); +static void process_stat(uint32_t id); +static void process_lstat(uint32_t id); +static void process_fstat(uint32_t id); +static void process_setstat(uint32_t id); +static void process_fsetstat(uint32_t id); +static void process_opendir(uint32_t id); +static void process_readdir(uint32_t id); +static void process_remove(uint32_t id); +static void process_mkdir(uint32_t id); +static void process_rmdir(uint32_t id); +static void process_realpath(uint32_t id); +static void process_rename(uint32_t id); +static void process_readlink(uint32_t id); +static void process_symlink(uint32_t id); +static void process_extended_posix_rename(uint32_t id); +static void process_extended_statvfs(uint32_t id); +static void process_extended_fstatvfs(uint32_t id); +static void process_extended_hardlink(uint32_t id); +static void process_extended_fsync(uint32_t id); +static void process_extended_lsetstat(uint32_t id); +static void process_extended_limits(uint32_t id); +static void process_extended_expand(uint32_t id); +static void process_extended_copy_data(uint32_t id); +static void process_extended_home_directory(uint32_t id); +static void process_extended_get_users_groups_by_id(uint32_t id); +static void process_extended(uint32_t id); struct sftp_handler { const char *name; /* user-visible name for fine-grained perms */ const char *ext_name; /* extended request name */ u_int type; /* packet type, for non extended packets */ - void (*handler)(u_int32_t); + void (*handler)(uint32_t); int does_write; /* if nonzero, banned for readonly mode */ }; @@ -313,7 +305,7 @@ struct Handle { int fd; int flags; char *name; - u_int64_t bytes_read, bytes_write; + uint64_t bytes_read, bytes_write; int next_unused; }; @@ -438,7 +430,7 @@ handle_update_write(int handle, ssize_t bytes) handles[handle].bytes_write += bytes; } -static u_int64_t +static uint64_t handle_bytes_read(int handle) { if (handle_is_ok(handle, HANDLE_FILE)) @@ -446,7 +438,7 @@ handle_bytes_read(int handle) return 0; } -static u_int64_t +static uint64_t handle_bytes_write(int handle) { if (handle_is_ok(handle, HANDLE_FILE)) @@ -528,7 +520,7 @@ send_msg(struct sshbuf *m) } static const char * -status_to_message(u_int32_t status) +status_to_message(uint32_t status) { static const char * const status_messages[] = { "Success", /* SSH_FX_OK */ @@ -546,7 +538,7 @@ status_to_message(u_int32_t status) } static void -send_status_errmsg(u_int32_t id, u_int32_t status, const char *errmsg) +send_status_errmsg(uint32_t id, uint32_t status, const char *errmsg) { struct sshbuf *msg; int r; @@ -572,13 +564,13 @@ send_status_errmsg(u_int32_t id, u_int32_t status, const char *errmsg) } static void -send_status(u_int32_t id, u_int32_t status) +send_status(uint32_t id, uint32_t status) { send_status_errmsg(id, status, NULL); } static void -send_data_or_handle(char type, u_int32_t id, const u_char *data, int dlen) +send_data_or_handle(char type, uint32_t id, const u_char *data, int dlen) { struct sshbuf *msg; int r; @@ -594,14 +586,14 @@ send_data_or_handle(char type, u_int32_t id, const u_char *data, int dlen) } static void -send_data(u_int32_t id, const u_char *data, int dlen) +send_data(uint32_t id, const u_char *data, int dlen) { debug("request %u: sent data len %d", id, dlen); send_data_or_handle(SSH2_FXP_DATA, id, data, dlen); } static void -send_handle(u_int32_t id, int handle) +send_handle(uint32_t id, int handle) { u_char *string; int hlen; @@ -613,7 +605,7 @@ send_handle(u_int32_t id, int handle) } static void -send_names(u_int32_t id, int count, const Stat *stats) +send_names(uint32_t id, int count, const Stat *stats) { struct sshbuf *msg; int i, r; @@ -636,7 +628,7 @@ send_names(u_int32_t id, int count, const Stat *stats) } static void -send_attrib(u_int32_t id, const Attrib *a) +send_attrib(uint32_t id, const Attrib *a) { struct sshbuf *msg; int r; @@ -653,10 +645,10 @@ send_attrib(u_int32_t id, const Attrib *a) } static void -send_statvfs(u_int32_t id, struct statvfs *st) +send_statvfs(uint32_t id, struct statvfs *st) { struct sshbuf *msg; - u_int64_t flag; + uint64_t flag; int r; flag = (st->f_flag & ST_RDONLY) ? SSH2_FXE_STATVFS_ST_RDONLY : 0; @@ -739,9 +731,9 @@ process_init(void) } static void -process_open(u_int32_t id) +process_open(uint32_t id) { - u_int32_t pflags; + uint32_t pflags; Attrib a; char *name; int r, handle, fd, flags, mode, status = SSH2_FX_FAILURE; @@ -781,7 +773,7 @@ process_open(u_int32_t id) } static void -process_close(u_int32_t id) +process_close(uint32_t id) { int r, handle, ret, status = SSH2_FX_FAILURE; @@ -796,13 +788,13 @@ process_close(u_int32_t id) } static void -process_read(u_int32_t id) +process_read(uint32_t id) { static u_char *buf; static size_t buflen; - u_int32_t len; + uint32_t len; int r, handle, fd, ret, status = SSH2_FX_FAILURE; - u_int64_t off; + uint64_t off; if ((r = get_handle(iqueue, &handle)) != 0 || (r = sshbuf_get_u64(iqueue, &off)) != 0 || @@ -851,9 +843,9 @@ process_read(u_int32_t id) } static void -process_write(u_int32_t id) +process_write(uint32_t id) { - u_int64_t off; + uint64_t off; size_t len; int r, handle, fd, ret, status; u_char *data; @@ -896,7 +888,7 @@ process_write(u_int32_t id) } static void -process_do_stat(u_int32_t id, int do_lstat) +process_do_stat(uint32_t id, int do_lstat) { Attrib a; struct stat st; @@ -922,19 +914,19 @@ process_do_stat(u_int32_t id, int do_lstat) } static void -process_stat(u_int32_t id) +process_stat(uint32_t id) { process_do_stat(id, 0); } static void -process_lstat(u_int32_t id) +process_lstat(uint32_t id) { process_do_stat(id, 1); } static void -process_fstat(u_int32_t id) +process_fstat(uint32_t id) { Attrib a; struct stat st; @@ -984,7 +976,7 @@ attrib_to_ts(const Attrib *a) } static void -process_setstat(u_int32_t id) +process_setstat(uint32_t id) { Attrib a; char *name; @@ -1031,7 +1023,7 @@ process_setstat(u_int32_t id) } static void -process_fsetstat(u_int32_t id) +process_fsetstat(uint32_t id) { Attrib a; int handle, fd, r; @@ -1096,7 +1088,7 @@ process_fsetstat(u_int32_t id) } static void -process_opendir(u_int32_t id) +process_opendir(uint32_t id) { DIR *dirp = NULL; char *path; @@ -1126,7 +1118,7 @@ process_opendir(u_int32_t id) } static void -process_readdir(u_int32_t id) +process_readdir(uint32_t id) { DIR *dirp; struct dirent *dp; @@ -1183,7 +1175,7 @@ process_readdir(u_int32_t id) } static void -process_remove(u_int32_t id) +process_remove(uint32_t id) { char *name; int r, status = SSH2_FX_FAILURE; @@ -1200,7 +1192,7 @@ process_remove(u_int32_t id) } static void -process_mkdir(u_int32_t id) +process_mkdir(uint32_t id) { Attrib a; char *name; @@ -1221,7 +1213,7 @@ process_mkdir(u_int32_t id) } static void -process_rmdir(u_int32_t id) +process_rmdir(uint32_t id) { char *name; int r, status; @@ -1238,7 +1230,7 @@ process_rmdir(u_int32_t id) } static void -process_realpath(u_int32_t id) +process_realpath(uint32_t id) { char resolvedname[PATH_MAX]; char *path; @@ -1265,7 +1257,7 @@ process_realpath(u_int32_t id) } static void -process_rename(u_int32_t id) +process_rename(uint32_t id) { char *oldpath, *newpath; int r, status; @@ -1325,7 +1317,7 @@ process_rename(u_int32_t id) } static void -process_readlink(u_int32_t id) +process_readlink(uint32_t id) { int r, len; char buf[PATH_MAX]; @@ -1350,7 +1342,7 @@ process_readlink(u_int32_t id) } static void -process_symlink(u_int32_t id) +process_symlink(uint32_t id) { char *oldpath, *newpath; int r, status; @@ -1370,7 +1362,7 @@ process_symlink(u_int32_t id) } static void -process_extended_posix_rename(u_int32_t id) +process_extended_posix_rename(uint32_t id) { char *oldpath, *newpath; int r, status; @@ -1389,7 +1381,7 @@ process_extended_posix_rename(u_int32_t id) } static void -process_extended_statvfs(u_int32_t id) +process_extended_statvfs(uint32_t id) { char *path; struct statvfs st; @@ -1408,7 +1400,7 @@ process_extended_statvfs(u_int32_t id) } static void -process_extended_fstatvfs(u_int32_t id) +process_extended_fstatvfs(uint32_t id) { int r, handle, fd; struct statvfs st; @@ -1428,7 +1420,7 @@ process_extended_fstatvfs(u_int32_t id) } static void -process_extended_hardlink(u_int32_t id) +process_extended_hardlink(uint32_t id) { char *oldpath, *newpath; int r, status; @@ -1447,7 +1439,7 @@ process_extended_hardlink(u_int32_t id) } static void -process_extended_fsync(u_int32_t id) +process_extended_fsync(uint32_t id) { int handle, fd, r, status = SSH2_FX_OP_UNSUPPORTED; @@ -1465,7 +1457,7 @@ process_extended_fsync(u_int32_t id) } static void -process_extended_lsetstat(u_int32_t id) +process_extended_lsetstat(uint32_t id) { Attrib a; char *name; @@ -1514,7 +1506,7 @@ process_extended_lsetstat(u_int32_t id) } static void -process_extended_limits(u_int32_t id) +process_extended_limits(uint32_t id) { struct sshbuf *msg; int r; @@ -1548,7 +1540,7 @@ process_extended_limits(u_int32_t id) } static void -process_extended_expand(u_int32_t id) +process_extended_expand(uint32_t id) { char cwd[PATH_MAX], resolvedname[PATH_MAX]; char *path, *npath; @@ -1607,11 +1599,11 @@ process_extended_expand(u_int32_t id) } static void -process_extended_copy_data(u_int32_t id) +process_extended_copy_data(uint32_t id) { u_char buf[64*1024]; int read_handle, read_fd, write_handle, write_fd; - u_int64_t len, read_off, read_len, write_off; + uint64_t len, read_off, read_len, write_off; int r, copy_until_eof, status = SSH2_FX_OP_UNSUPPORTED; size_t ret; @@ -1620,7 +1612,7 @@ process_extended_copy_data(u_int32_t id) (r = sshbuf_get_u64(iqueue, &read_len)) != 0 || (r = get_handle(iqueue, &write_handle)) != 0 || (r = sshbuf_get_u64(iqueue, &write_off)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); debug("request %u: copy-data from \"%s\" (handle %d) off %llu len %llu " "to \"%s\" (handle %d) off %llu", @@ -1631,7 +1623,7 @@ process_extended_copy_data(u_int32_t id) /* For read length of 0, we read until EOF. */ if (read_len == 0) { - read_len = (u_int64_t)-1 - read_off; + read_len = (uint64_t)-1 - read_off; copy_until_eof = 1; } else copy_until_eof = 0; @@ -1648,14 +1640,14 @@ process_extended_copy_data(u_int32_t id) if (lseek(read_fd, read_off, SEEK_SET) < 0) { status = errno_to_portable(errno); - error("%s: read_seek failed", __func__); + error_f("read_seek failed"); goto out; } if ((handle_to_flags(write_handle) & O_APPEND) == 0 && lseek(write_fd, write_off, SEEK_SET) < 0) { status = errno_to_portable(errno); - error("%s: write_seek failed", __func__); + error_f("write_seek failed"); goto out; } @@ -1670,7 +1662,7 @@ process_extended_copy_data(u_int32_t id) break; } else if (ret == 0) { status = errno_to_portable(errno); - error("%s: read failed: %s", __func__, strerror(errno)); + error_f("read failed: %s", strerror(errno)); break; } len = ret; @@ -1695,7 +1687,7 @@ process_extended_copy_data(u_int32_t id) } static void -process_extended_home_directory(u_int32_t id) +process_extended_home_directory(uint32_t id) { char *username; struct passwd *user_pw; @@ -1722,7 +1714,7 @@ process_extended_home_directory(u_int32_t id) } static void -process_extended_get_users_groups_by_id(u_int32_t id) +process_extended_get_users_groups_by_id(uint32_t id) { struct passwd *user_pw; struct group *gr; @@ -1758,7 +1750,7 @@ process_extended_get_users_groups_by_id(u_int32_t id) debug3_f("gid %u => \"%s\"", n, name); if ((r = sshbuf_put_cstring(groupnames, name)) != 0) fatal_fr(r, "assemble gid reply"); - nusers++; + ngroups++; } verbose("users-groups-by-id: %u users, %u groups", nusers, ngroups); @@ -1777,7 +1769,7 @@ process_extended_get_users_groups_by_id(u_int32_t id) } static void -process_extended(u_int32_t id) +process_extended(uint32_t id) { char *request; int r; @@ -1808,7 +1800,7 @@ process(void) u_char type; const u_char *cp; int i, r; - u_int32_t id; + uint32_t id; buf_len = sshbuf_len(iqueue); if (buf_len < 5) diff --git a/sftp-usergroup.c b/sftp-usergroup.c index 93396ff..d931b29 100644 --- a/sftp-usergroup.c +++ b/sftp-usergroup.c @@ -19,8 +19,9 @@ #include "includes.h" #include -#include +#include +#include #include #include #include diff --git a/sftp.0 b/sftp.0 index 97fde6a..a0e20e3 100644 --- a/sftp.0 +++ b/sftp.0 @@ -116,67 +116,106 @@ DESCRIPTION of the options listed below, and their possible values, see ssh_config(5). + AddKeysToAgent AddressFamily BatchMode BindAddress BindInterface + CASignatureAlgorithms CanonicalDomains CanonicalizeFallbackLocal CanonicalizeHostname CanonicalizeMaxDots CanonicalizePermittedCNAMEs - CASignatureAlgorithms CertificateFile + ChannelTimeout CheckHostIP Ciphers + ClearAllForwardings Compression - ConnectionAttempts ConnectTimeout + ConnectionAttempts ControlMaster ControlPath ControlPersist - GlobalKnownHostsFile + DynamicForward + EnableEscapeCommandline + EnableSSHKeysign + EscapeChar + ExitOnForwardFailure + FingerprintHash + ForkAfterAuthentication + ForwardAgent + ForwardX11 + ForwardX11Timeout + ForwardX11Trusted GSSAPIAuthentication GSSAPIDelegateCredentials + GatewayPorts + GlobalKnownHostsFile HashKnownHosts Host - HostbasedAcceptedAlgorithms - HostbasedAuthentication HostKeyAlgorithms HostKeyAlias + HostbasedAcceptedAlgorithms + HostbasedAuthentication Hostname + IPQoS IdentitiesOnly IdentityAgent IdentityFile - IPQoS + IgnoreUnknown + Include KbdInteractiveAuthentication KbdInteractiveDevices KexAlgorithms KnownHostsCommand + LocalCommand + LocalForward LogLevel + LogVerbose MACs NoHostAuthenticationForLocalhost NumberOfPasswordPrompts - PasswordAuthentication + ObscureKeystrokeTiming PKCS11Provider + PasswordAuthentication + PermitLocalCommand + PermitRemoteOpen Port PreferredAuthentications ProxyCommand ProxyJump + ProxyUseFdpass PubkeyAcceptedAlgorithms PubkeyAuthentication RekeyLimit + RemoteCommand + RemoteForward + RequestTTY RequiredRSASize + RevokedHostKeys + SecurityKeyProvider SendEnv - ServerAliveInterval ServerAliveCountMax + ServerAliveInterval + SessionType SetEnv + StdinNull + StreamLocalBindMask + StreamLocalBindUnlink StrictHostKeyChecking + SyslogFacility TCPKeepAlive + Tag + Tunnel + TunnelDevice UpdateHostKeys User UserKnownHostsFile VerifyHostKeyDNS + VisualHostKey + XAuthLocation -P port Specifies the port to connect to on the remote host. @@ -435,4 +474,4 @@ SEE ALSO T. Ylonen and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh- filexfer-00.txt, January 2001, work in progress material. -OpenBSD 7.6 December 16, 2022 OpenBSD 7.6 +OpenBSD 7.8 December 6, 2024 SFTP(1) diff --git a/sftp.1 b/sftp.1 index 68923ae..651baaf 100644 --- a/sftp.1 +++ b/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.143 2022/12/16 03:40:03 djm Exp $ +.\" $OpenBSD: sftp.1,v 1.144 2024/12/06 15:12:56 djm Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: December 16 2022 $ +.Dd $Mdocdate: December 6 2024 $ .Dt SFTP 1 .Os .Sh NAME @@ -224,67 +224,106 @@ For full details of the options listed below, and their possible values, see .Xr ssh_config 5 . .Pp .Bl -tag -width Ds -offset indent -compact +.It AddKeysToAgent .It AddressFamily .It BatchMode .It BindAddress .It BindInterface +.It CASignatureAlgorithms .It CanonicalDomains .It CanonicalizeFallbackLocal .It CanonicalizeHostname .It CanonicalizeMaxDots .It CanonicalizePermittedCNAMEs -.It CASignatureAlgorithms .It CertificateFile +.It ChannelTimeout .It CheckHostIP .It Ciphers +.It ClearAllForwardings .It Compression -.It ConnectionAttempts .It ConnectTimeout +.It ConnectionAttempts .It ControlMaster .It ControlPath .It ControlPersist -.It GlobalKnownHostsFile +.It DynamicForward +.It EnableEscapeCommandline +.It EnableSSHKeysign +.It EscapeChar +.It ExitOnForwardFailure +.It FingerprintHash +.It ForkAfterAuthentication +.It ForwardAgent +.It ForwardX11 +.It ForwardX11Timeout +.It ForwardX11Trusted .It GSSAPIAuthentication .It GSSAPIDelegateCredentials +.It GatewayPorts +.It GlobalKnownHostsFile .It HashKnownHosts .It Host -.It HostbasedAcceptedAlgorithms -.It HostbasedAuthentication .It HostKeyAlgorithms .It HostKeyAlias +.It HostbasedAcceptedAlgorithms +.It HostbasedAuthentication .It Hostname +.It IPQoS .It IdentitiesOnly .It IdentityAgent .It IdentityFile -.It IPQoS +.It IgnoreUnknown +.It Include .It KbdInteractiveAuthentication .It KbdInteractiveDevices .It KexAlgorithms .It KnownHostsCommand +.It LocalCommand +.It LocalForward .It LogLevel +.It LogVerbose .It MACs .It NoHostAuthenticationForLocalhost .It NumberOfPasswordPrompts -.It PasswordAuthentication +.It ObscureKeystrokeTiming .It PKCS11Provider +.It PasswordAuthentication +.It PermitLocalCommand +.It PermitRemoteOpen .It Port .It PreferredAuthentications .It ProxyCommand .It ProxyJump +.It ProxyUseFdpass .It PubkeyAcceptedAlgorithms .It PubkeyAuthentication .It RekeyLimit +.It RemoteCommand +.It RemoteForward +.It RequestTTY .It RequiredRSASize +.It RevokedHostKeys +.It SecurityKeyProvider .It SendEnv -.It ServerAliveInterval .It ServerAliveCountMax +.It ServerAliveInterval +.It SessionType .It SetEnv +.It StdinNull +.It StreamLocalBindMask +.It StreamLocalBindUnlink .It StrictHostKeyChecking +.It SyslogFacility .It TCPKeepAlive +.It Tag +.It Tunnel +.It TunnelDevice .It UpdateHostKeys .It User .It UserKnownHostsFile .It VerifyHostKeyDNS +.It VisualHostKey +.It XAuthLocation .El .It Fl P Ar port Specifies the port to connect to on the remote host. diff --git a/sftp.c b/sftp.c index 360c500..eebb166 100644 --- a/sftp.c +++ b/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.239 2024/06/26 23:14:14 deraadt Exp $ */ +/* $OpenBSD: sftp.c,v 1.250 2026/02/11 17:01:34 dtucker Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -19,24 +19,16 @@ #include #include -#ifdef HAVE_SYS_STAT_H -# include -#endif +#include #include -#include -#ifdef HAVE_SYS_STATVFS_H #include -#endif +#include #include #include - -#ifdef HAVE_PATHS_H -# include -#endif -#ifdef HAVE_LIBGEN_H +#include +#include #include -#endif #ifdef HAVE_LOCALE_H # include #endif @@ -52,10 +44,7 @@ typedef void EditLine; #include #include #include - -#ifdef HAVE_UTIL_H -# include -#endif +#include #include "xmalloc.h" #include "log.h" @@ -687,6 +676,10 @@ process_get(struct sftp_conn *conn, const char *src, const char *dst, goto out; } + /* Special handling for dest of '..' */ + if (strcmp(filename, "..") == 0) + filename = "."; /* Download to dest, not dest/.. */ + if (g.gl_matchc == 1 && dst) { if (local_is_dir(dst)) { abs_dst = sftp_path_append(dst, filename); @@ -781,6 +774,9 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst, err = -1; goto out; } + /* Special handling for source of '..' */ + if (strcmp(filename, "..") == 0) + filename = "."; /* Upload to dest, not dest/.. */ free(abs_dst); abs_dst = NULL; @@ -1865,35 +1861,50 @@ complete_display(char **list, u_int len) /* * Given a "list" of words that begin with a common prefix of "word", - * attempt to find an autocompletion to extends "word" by the next + * attempt to find an autocompletion that extends "word" by the next * characters common to all entries in "list". */ static char * complete_ambiguous(const char *word, char **list, size_t count) { + size_t i, j, matchlen; + char *tmp; + int len; + if (word == NULL) return NULL; - if (count > 0) { - u_int y, matchlen = strlen(list[0]); - - /* Find length of common stem */ - for (y = 1; list[y]; y++) { - u_int x; + if (count == 0) + return xstrdup(word); /* no options to complete */ - for (x = 0; x < matchlen; x++) - if (list[0][x] != list[y][x]) - break; - - matchlen = x; - } - - if (matchlen > strlen(word)) { - char *tmp = xstrdup(list[0]); + /* Find length of common stem across list */ + matchlen = strlen(list[0]); + for (i = 1; i < count && list[i] != NULL; i++) { + for (j = 0; j < matchlen; j++) + if (list[0][j] != list[i][j]) + break; + matchlen = j; + } - tmp[matchlen] = '\0'; - return tmp; - } + /* + * Now check that the common stem doesn't finish in the middle of + * a multibyte character. + */ + mblen(NULL, 0); + for (i = 0; i < matchlen;) { + len = mblen(list[0] + i, matchlen - i); + if (len <= 0 || i + (size_t)len > matchlen) + break; + i += (size_t)len; + } + /* If so, truncate */ + if (i < matchlen) + matchlen = i; + + if (matchlen > strlen(word)) { + tmp = xstrdup(list[0]); + tmp[matchlen] = '\0'; + return tmp; } return xstrdup(word); @@ -2073,6 +2084,7 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path, tmp2 = tmp + filelen - cesc; len = strlen(tmp2); /* quote argument on way out */ + mblen(NULL, 0); for (i = 0; i < len; i += clen) { if ((clen = mblen(tmp2 + i, len - i)) < 0 || (size_t)clen > sizeof(ins) - 2) @@ -2213,6 +2225,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2) int err, interactive; EditLine *el = NULL; #ifdef USE_LIBEDIT + const char *editor; History *hl = NULL; HistEvent hev; extern char *__progname; @@ -2246,6 +2259,10 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2) el_set(el, EL_BIND, "\\e\\e[D", "ed-prev-word", NULL); /* make ^w match ksh behaviour */ el_set(el, EL_BIND, "^w", "ed-delete-prev-word", NULL); + + /* el_source() may have changed EL_EDITOR to vi */ + if (el_get(el, EL_EDITOR, &editor) == 0 && editor[0] == 'v') + el_set(el, EL_BIND, "^[", "vi-command-mode", NULL); } #endif /* USE_LIBEDIT */ @@ -2351,6 +2368,8 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2) free(conn); #ifdef USE_LIBEDIT + if (hl != NULL) + history_end(hl); if (el != NULL) el_end(el); #endif /* USE_LIBEDIT */ @@ -2463,6 +2482,7 @@ main(int argc, char **argv) addargs(&args, "-oForwardX11 no"); addargs(&args, "-oPermitLocalCommand no"); addargs(&args, "-oClearAllForwardings yes"); + addargs(&args, "-oControlMaster no"); ll = SYSLOG_LEVEL_INFO; infile = stdin; @@ -2661,7 +2681,7 @@ main(int argc, char **argv) } else { if ((r = argv_split(sftp_direct, &tmp, &cpp, 1)) != 0) fatal_r(r, "Parse -D arguments"); - if (cpp[0] == 0) + if (cpp[0] == NULL) fatal("No sftp server specified via -D"); connect_to_server(cpp[0], cpp, &in, &out); argv_free(cpp, tmp); diff --git a/sk-api.h b/sk-api.h index 08f567a..32d0f11 100644 --- a/sk-api.h +++ b/sk-api.h @@ -19,9 +19,7 @@ #define _SK_API_H 1 #include -#ifdef HAVE_STDINT_H #include -#endif /* Flags */ #define SSH_SK_USER_PRESENCE_REQD 0x01 diff --git a/sk-usbhid.c b/sk-usbhid.c index 812b28d..cd24881 100644 --- a/sk-usbhid.c +++ b/sk-usbhid.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sk-usbhid.c,v 1.46 2023/03/28 06:12:38 dtucker Exp $ */ +/* $OpenBSD: sk-usbhid.c,v 1.48 2025/05/12 05:41:20 tb Exp $ */ /* * Copyright (c) 2019 Markus Friedl * Copyright (c) 2020 Pedro Martelletto @@ -20,9 +20,7 @@ #ifdef ENABLE_SK_INTERNAL -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include #include @@ -49,6 +47,7 @@ #include #include #include +#include "openbsd-compat/openssl-compat.h" #endif /* WITH_OPENSSL */ #include @@ -77,10 +76,11 @@ #define FIDO_CRED_PROT_UV_OPTIONAL_WITH_ID 0 #endif +# include "misc.h" + #ifndef SK_STANDALONE # include "log.h" # include "xmalloc.h" -# include "misc.h" /* * If building as part of OpenSSH, then rename exported functions. * This must be done before including sk-api.h. @@ -635,8 +635,8 @@ pack_public_key_ecdsa(const fido_cred_t *cred, skdebug(__func__, "BN_bin2bn failed"); goto out; } - if (EC_POINT_set_affine_coordinates_GFp(g, q, x, y, NULL) != 1) { - skdebug(__func__, "EC_POINT_set_affine_coordinates_GFp failed"); + if (EC_POINT_set_affine_coordinates(g, q, x, y, NULL) != 1) { + skdebug(__func__, "EC_POINT_set_affine_coordinates failed"); goto out; } response->public_key_len = EC_POINT_point2oct(g, q, @@ -960,13 +960,15 @@ sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len, fido_strerr(r)); goto out; } - } else { + } else if (strcmp(fido_cred_fmt(cred), "none") != 0) { skdebug(__func__, "self-attested credential"); if ((r = fido_cred_verify_self(cred)) != FIDO_OK) { skdebug(__func__, "fido_cred_verify_self: %s", fido_strerr(r)); goto out; } + } else { + skdebug(__func__, "no attestation data"); } if ((response = calloc(1, sizeof(*response))) == NULL) { skdebug(__func__, "calloc response failed"); diff --git a/sntrup761.c b/sntrup761.c index 123d013..a731e56 100644 --- a/sntrup761.c +++ b/sntrup761.c @@ -1,5 +1,4 @@ - -/* $OpenBSD: sntrup761.c,v 1.8 2024/09/16 05:37:05 djm Exp $ */ +/* $OpenBSD: sntrup761.c,v 1.9 2026/01/20 22:56:11 dtucker Exp $ */ /* * Public Domain, Authors: @@ -1961,27 +1960,20 @@ static void Hash_prefix(unsigned char *out, int b, const unsigned char *in, int for (i = 0; i < 32; ++i) out[i] = h[i]; } -static uint32_t urandom32(void) { - unsigned char c[4]; - uint32_t result = 0; - int i; - randombytes(c, 4); - for (i = 0; i < 4; ++i) result += ((uint32_t)c[i]) << (8 * i); - return result; -} static void Short_random(small *out) { uint32_t L[p]; - int i; - for (i = 0; i < p; ++i) L[i] = urandom32(); + randombytes(L, sizeof(L)); Short_fromlist(out, L); + explicit_bzero(L, sizeof(L)); } - static void Small_random(small *out) { int i; - for (i = 0; i < p; ++i) out[i] = (((urandom32() & 0x3fffffff) * 3) >> 30) - 1; + uint32_t L[p]; + randombytes(L, sizeof(L)); + for (i = 0; i < p; ++i) out[i] = (((L[i] & 0x3fffffff) * 3) >> 30) - 1; + explicit_bzero(L, sizeof(L)); } - static void KeyGen(Fq *h, small *f, small *ginv) { small g[p]; Fq finv[p]; diff --git a/sntrup761.sh b/sntrup761.sh index 4de8dc3..d4da991 100644 --- a/sntrup761.sh +++ b/sntrup761.sh @@ -1,5 +1,5 @@ #!/bin/sh -# $OpenBSD: sntrup761.sh,v 1.9 2024/09/16 05:37:05 djm Exp $ +# $OpenBSD: sntrup761.sh,v 1.10 2026/01/20 22:56:11 dtucker Exp $ # Placed in the Public Domain. # AUTHOR="supercop-20240808/crypto_kem/sntrup761/ref/implementors" @@ -87,6 +87,28 @@ for i in $FILES; do */uint32/useint32/sort.c) sed -e "s/void crypto_sort/void crypto_sort_uint32/g" ;; + # Replace Short_random and Small_random with versions that fetch + # entropy in a single operation, then delete urandom32 as unused. + */crypto_kem/sntrup761/compact/kem.c) + sed -e '/ uint32_t urandom32/,/^}$/d' \ + -e '/ void Short_random/i\ +static void Short_random(small *out) {\ + uint32_t L[p];\ + randombytes(L, sizeof(L));\ + Short_fromlist(out, L);\ + explicit_bzero(L, sizeof(L));\ +}' \ + -e '/ void Short_random(/,/^}$/d' \ + -e '/ void Small_random/i\ +static void Small_random(small *out) {\ + int i;\ + uint32_t L[p];\ + randombytes(L, sizeof(L));\ + for (i = 0; i < p; ++i) out[i] = (((L[i] & 0x3fffffff) * 3) >> 30) - 1;\ + explicit_bzero(L, sizeof(L));\ +}' \ + -e '/ void Small_random(/,/^}$/d' + ;; # Remove unused function to prevent warning. */crypto_kem/sntrup761/ref/int32.c) sed -e '/ int32_div_uint14/,/^}$/d' diff --git a/srclimit.c b/srclimit.c index 33116fa..05f22ee 100644 --- a/srclimit.c +++ b/srclimit.c @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include @@ -53,7 +53,7 @@ static struct child_info { */ struct penalty { struct xaddr addr; - time_t expiry; + double expiry; int active; const char *reason; RB_ENTRY(penalty) by_addr; @@ -119,7 +119,7 @@ srclimit_init(int max, int persource, int ipv4len, int ipv6len, debug("%s: max connections %d, per source %d, masks %d,%d", __func__, max, persource, ipv4len, ipv6len); if (max <= 0) - fatal("%s: invalid number of sockets: %d", __func__, max); + fatal_f("invalid number of sockets: %d", max); children = xcalloc(max_children, sizeof(*children)); for (i = 0; i < max_children; i++) children[i].id = -1; @@ -136,7 +136,7 @@ srclimit_check_allow(int sock, int id) if (max_persource == INT_MAX) /* no limit */ return 1; - debug("%s: sock %d id %d limit %d", __func__, sock, id, max_persource); + debug_f("sock %d id %d limit %d", sock, id, max_persource); if (srclimit_peer_addr(sock, &xa) != 0) return 1; bits = xa.af == AF_INET ? ipv4_masklen : ipv6_masklen; @@ -154,14 +154,14 @@ srclimit_check_allow(int sock, int id) } } if (addr_ntop(&xa, xas, sizeof(xas)) != 0) { - debug3("%s: addr ntop failed", __func__); + debug3_f("addr ntop failed"); return 1; } debug3("%s: new unauthenticated connection from %s/%d, at %d of %d", __func__, xas, bits, count, max_persource); if (first_unused == max_children) { /* no free slot found */ - debug3("%s: no free slot", __func__); + debug3_f("no free slot"); return 0; } if (first_unused < 0 || first_unused >= max_children) @@ -185,7 +185,7 @@ srclimit_done(int id) if (max_persource == INT_MAX) /* no limit */ return; - debug("%s: id %d", __func__, id); + debug_f("id %d", id); /* Clear corresponding state entry. */ for (i = 0; i < max_children; i++) { if (children[i].id == id) { @@ -212,7 +212,7 @@ penalty_expiry_cmp(struct penalty *a, struct penalty *b) } static void -expire_penalties_from_tree(time_t now, const char *t, +expire_penalties_from_tree(double now, const char *t, struct penalties_by_expiry *by_expiry, struct penalties_by_addr *by_addr, size_t *npenaltiesp) { @@ -234,7 +234,7 @@ expire_penalties_from_tree(time_t now, const char *t, } static void -expire_penalties(time_t now) +expire_penalties(double now) { expire_penalties_from_tree(now, "ipv4", &penalties_by_expiry4, &penalties_by_addr4, &npenalties4); @@ -260,7 +260,7 @@ srclimit_penalty_check_allow(int sock, const char **reason) { struct xaddr addr; struct penalty find, *penalty; - time_t now; + double now; int bits, max_sources, overflow_mode; char addr_s[NI_MAXHOST]; struct penalties_by_addr *by_addr; @@ -277,7 +277,7 @@ srclimit_penalty_check_allow(int sock, const char **reason) return 1; } } - now = monotime(); + now = monotime_double(); expire_penalties(now); by_addr = addr.af == AF_INET ? &penalties_by_addr4 : &penalties_by_addr6; @@ -347,8 +347,9 @@ srclimit_penalise(struct xaddr *addr, int penalty_type) { struct xaddr masked; struct penalty *penalty = NULL, *existing = NULL; - time_t now; - int bits, penalty_secs, max_sources = 0, overflow_mode; + double now; + int bits, max_sources = 0, overflow_mode; + double penalty_secs; char addrnetmask[NI_MAXHOST + 4]; const char *reason = NULL, *t; size_t *npenaltiesp = NULL; @@ -381,23 +382,31 @@ srclimit_penalise(struct xaddr *addr, int penalty_type) penalty_secs = penalty_cfg.penalty_noauth; reason = "penalty: connections without attempting authentication"; break; + case SRCLIMIT_PENALTY_INVALIDUSER: + penalty_secs = penalty_cfg.penalty_invaliduser; + reason = "penalty: attempted authentication by invalid user"; + break; case SRCLIMIT_PENALTY_REFUSECONNECTION: penalty_secs = penalty_cfg.penalty_refuseconnection; reason = "penalty: connection prohibited by RefuseConnection"; break; case SRCLIMIT_PENALTY_GRACE_EXCEEDED: - penalty_secs = penalty_cfg.penalty_crash; + penalty_secs = penalty_cfg.penalty_grace; reason = "penalty: exceeded LoginGraceTime"; break; default: fatal_f("internal error: unknown penalty %d", penalty_type); } + + if (penalty_secs <= 0) + return; + bits = addr->af == AF_INET ? ipv4_masklen : ipv6_masklen; if (srclimit_mask_addr(addr, bits, &masked) != 0) return; addr_masklen_ntop(addr, bits, addrnetmask, sizeof(addrnetmask)); - now = monotime(); + now = monotime_double(); expire_penalties(now); by_expiry = addr->af == AF_INET ? &penalties_by_expiry4 : &penalties_by_expiry6; @@ -427,7 +436,9 @@ srclimit_penalise(struct xaddr *addr, int penalty_type) penalty->active = 1; if (RB_INSERT(penalties_by_expiry, by_expiry, penalty) != NULL) fatal_f("internal error: %s penalty tables corrupt", t); - verbose_f("%s: new %s %s penalty of %d seconds for %s", t, + do_log2_f(penalty->active ? + SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_VERBOSE, + "%s: new %s %s penalty of %.3f seconds for %s", t, addrnetmask, penalty->active ? "active" : "deferred", penalty_secs, reason); if (++(*npenaltiesp) > (size_t)max_sources) @@ -446,9 +457,8 @@ srclimit_penalise(struct xaddr *addr, int penalty_type) existing->expiry = now + penalty_cfg.penalty_max; if (existing->expiry - now > penalty_cfg.penalty_min && !existing->active) { - verbose_f("%s: activating %s penalty of %lld seconds for %s", - addrnetmask, t, (long long)(existing->expiry - now), - reason); + logit_f("%s: activating %s penalty of %.3f seconds for %s", + addrnetmask, t, existing->expiry - now, reason); existing->active = 1; } existing->reason = penalty->reason; @@ -466,9 +476,9 @@ srclimit_penalty_info_for_tree(const char *t, struct penalty *p = NULL; int bits; char s[NI_MAXHOST + 4]; - time_t now; + double now; - now = monotime(); + now = monotime_double(); logit("%zu active %s penalties", npenalties, t); RB_FOREACH(p, penalties_by_expiry, by_expiry) { bits = p->addr.af == AF_INET ? ipv4_masklen : ipv6_masklen; @@ -476,8 +486,8 @@ srclimit_penalty_info_for_tree(const char *t, if (p->expiry < now) logit("client %s %s (expired)", s, p->reason); else { - logit("client %s %s (%llu secs left)", s, p->reason, - (long long)(p->expiry - now)); + logit("client %s %s (%.3f secs left)", s, p->reason, + p->expiry - now); } } } diff --git a/srclimit.h b/srclimit.h index 77d951b..3e083df 100644 --- a/srclimit.h +++ b/srclimit.h @@ -28,12 +28,14 @@ void srclimit_done(int); #define SRCLIMIT_PENALTY_GRACE_EXCEEDED 3 #define SRCLIMIT_PENALTY_NOAUTH 4 #define SRCLIMIT_PENALTY_REFUSECONNECTION 5 +#define SRCLIMIT_PENALTY_INVALIDUSER 6 /* meaningful exit values, used by sshd listener for penalties */ #define EXIT_LOGIN_GRACE 3 /* login grace period exceeded */ #define EXIT_CHILD_CRASH 4 /* preauth child crashed */ #define EXIT_AUTH_ATTEMPTED 5 /* at least one auth attempt made */ #define EXIT_CONFIG_REFUSED 6 /* sshd_config RefuseConnection */ +#define EXIT_INVALID_USER 7 /* invalid user supplied */ void srclimit_penalise(struct xaddr *, int); int srclimit_penalty_check_allow(int, const char **); diff --git a/ssh-add.0 b/ssh-add.0 index af99011..dfdf71f 100644 --- a/ssh-add.0 +++ b/ssh-add.0 @@ -4,11 +4,12 @@ NAME ssh-add M-bM-^@M-^S adds private key identities to the OpenSSH authentication agent SYNOPSIS - ssh-add [-CcDdKkLlqvXx] [-E fingerprint_hash] [-H hostkey_file] + ssh-add [-CcDdKkLlNqvXx] [-E fingerprint_hash] [-H hostkey_file] [-h destination_constraint] [-S provider] [-t life] [file ...] ssh-add -s pkcs11 [-Cv] [certificate ...] ssh-add -e pkcs11 ssh-add -T pubkey ... + ssh-add -Q DESCRIPTION ssh-add adds private key identities to the authentication agent, @@ -120,6 +121,15 @@ DESCRIPTION -l Lists fingerprints of all identities currently represented by the agent. + -N When adding certificates, by default ssh-add will request that + the agent automatically delete the certificate shortly after the + certificate's expiry date. This flag suppresses this behaviour + and does not specify a lifetime for certificates added to an + agent. + + -Q Query the agent for the list of protocol extensions it supports. + Note: not all agents support this query. + -q Be quiet after a successful operation. -S provider @@ -171,7 +181,7 @@ ENVIRONMENT input regardless of whether DISPLAY is set. SSH_AUTH_SOCK - Identifies the path of a UNIX-domain socket used to communicate + Identifies the path of a Unix-domain socket used to communicate with the agent. SSH_SK_PROVIDER @@ -206,4 +216,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 7.6 June 17, 2024 OpenBSD 7.6 +OpenBSD 7.8 March 5, 2026 SSH-ADD(1) diff --git a/ssh-add.1 b/ssh-add.1 index c31de4d..af5f8f7 100644 --- a/ssh-add.1 +++ b/ssh-add.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-add.1,v 1.87 2024/06/17 08:30:29 djm Exp $ +.\" $OpenBSD: ssh-add.1,v 1.89 2026/03/05 05:44:15 djm Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -35,7 +35,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: June 17 2024 $ +.Dd $Mdocdate: March 5 2026 $ .Dt SSH-ADD 1 .Os .Sh NAME @@ -43,7 +43,7 @@ .Nd adds private key identities to the OpenSSH authentication agent .Sh SYNOPSIS .Nm ssh-add -.Op Fl CcDdKkLlqvXx +.Op Fl CcDdKkLlNqvXx .Op Fl E Ar fingerprint_hash .Op Fl H Ar hostkey_file .Op Fl h Ar destination_constraint @@ -59,6 +59,8 @@ .Nm ssh-add .Fl T .Ar pubkey ... +.Nm ssh-add +.Fl Q .Sh DESCRIPTION .Nm adds private key identities to the authentication agent, @@ -223,6 +225,16 @@ Lists public key parameters of all identities currently represented by the agent. .It Fl l Lists fingerprints of all identities currently represented by the agent. +.It Fl N +When adding certificates, by default +.Nm +will request that the agent automatically delete the certificate shortly +after the certificate's expiry date. +This flag suppresses this behaviour and does not specify a lifetime for +certificates added to an agent. +.It Fl Q +Query the agent for the list of protocol extensions it supports. +Note: not all agents support this query. .It Fl q Be quiet after a successful operation. .It Fl S Ar provider diff --git a/ssh-add.c b/ssh-add.c index 0035cb8..1e9eddf 100644 --- a/ssh-add.c +++ b/ssh-add.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-add.c,v 1.173 2024/09/06 02:30:44 djm Exp $ */ +/* $OpenBSD: ssh-add.c,v 1.186 2026/03/05 05:44:15 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -54,6 +54,7 @@ #include #include #include +#include #include "xmalloc.h" #include "ssh.h" @@ -70,6 +71,8 @@ #include "sk-api.h" #include "hostfile.h" +#define CERT_EXPIRY_GRACE (5*60) + /* argv0 */ extern char *__progname; @@ -84,10 +87,6 @@ static char *default_files[] = { #endif /* WITH_OPENSSL */ _PATH_SSH_CLIENT_ID_ED25519, _PATH_SSH_CLIENT_ID_ED25519_SK, - _PATH_SSH_CLIENT_ID_XMSS, -#ifdef WITH_DSA - _PATH_SSH_CLIENT_ID_DSA, -#endif NULL }; @@ -99,10 +98,6 @@ static int lifetime = 0; /* User has to confirm key use */ static int confirm = 0; -/* Maximum number of signatures (XMSS) */ -static u_int maxsign = 0; -static u_int minleft = 0; - /* we keep a cache of one passphrase */ static char *pass = NULL; static void @@ -242,20 +237,52 @@ delete_all(int agent_fd, int qflag) return ret; } +static int +query_exts(int agent_fd) +{ + int r; + char **exts = NULL; + size_t i; + + if ((r = ssh_agent_query_extensions(agent_fd, &exts)) != 0) + fatal_r(r, "unable to query supported extensions"); + for (i = 0; exts != NULL && exts[i] != NULL; i++) + puts(exts[i]); + stringlist_free(exts); + return 0; +} + +static int +check_cert_lifetime(const struct sshkey *cert, int cert_lifetime) +{ + time_t now; + uint64_t n; + + if (cert == NULL || cert->cert == NULL || !sshkey_is_cert(cert) || + cert->cert->valid_before == 0xFFFFFFFFFFFFFFFFULL) + return cert_lifetime; + if ((now = time(NULL)) <= 0) + fatal_f("system time is at/before epoch"); + if ((uint64_t)now > (cert->cert->valid_before + CERT_EXPIRY_GRACE)) + return -1; /* certificate already expired */ + n = (CERT_EXPIRY_GRACE + cert->cert->valid_before) - (uint64_t)now; + n = MINIMUM(n, INT_MAX); + if (cert_lifetime <= 0) + return (int)n; + return MINIMUM(cert_lifetime, (int)n); +} + static int add_file(int agent_fd, const char *filename, int key_only, int cert_only, - int qflag, const char *skprovider, + int qflag, int Nflag, const char *skprovider, struct dest_constraint **dest_constraints, size_t ndest_constraints) { - struct sshkey *private, *cert; + struct sshkey *private = NULL, *cert = NULL; char *comment = NULL; char msg[1024], *certpath = NULL; - int r, fd, ret = -1; - size_t i; - u_int32_t left; + int cert_lifetime, r, fd, ret = -1; struct sshbuf *keyblob; - struct ssh_identitylist *idlist; if (strcmp(filename, "-") == 0) { fd = STDIN_FILENO; @@ -331,38 +358,6 @@ add_file(int agent_fd, const char *filename, int key_only, int cert_only, comment = xstrdup(filename); sshbuf_free(keyblob); - /* For XMSS */ - if ((r = sshkey_set_filename(private, filename)) != 0) { - fprintf(stderr, "Could not add filename to private key: %s (%s)\n", - filename, comment); - goto out; - } - if (maxsign && minleft && - (r = ssh_fetch_identitylist(agent_fd, &idlist)) == 0) { - for (i = 0; i < idlist->nkeys; i++) { - if (!sshkey_equal_public(idlist->keys[i], private)) - continue; - left = sshkey_signatures_left(idlist->keys[i]); - if (left < minleft) { - fprintf(stderr, - "Only %d signatures left.\n", left); - break; - } - fprintf(stderr, "Skipping update: "); - if (left == minleft) { - fprintf(stderr, - "required signatures left (%d).\n", left); - } else { - fprintf(stderr, - "more signatures left (%d) than" - " required (%d).\n", left, minleft); - } - ssh_free_identitylist(idlist); - goto out; - } - ssh_free_identitylist(idlist); - } - if (sshkey_is_sk(private)) { if (skprovider == NULL) { fprintf(stderr, "Cannot load FIDO key %s " @@ -374,26 +369,27 @@ add_file(int agent_fd, const char *filename, int key_only, int cert_only, skprovider = NULL; } - if (!cert_only && - (r = ssh_add_identity_constrained(agent_fd, private, comment, - lifetime, confirm, maxsign, skprovider, - dest_constraints, ndest_constraints)) == 0) { - ret = 0; - if (!qflag) { - fprintf(stderr, "Identity added: %s (%s)\n", - filename, comment); - if (lifetime != 0) { - fprintf(stderr, - "Lifetime set to %d seconds\n", lifetime); - } - if (confirm != 0) { - fprintf(stderr, "The user must confirm " - "each use of the key\n"); + if (!cert_only) { + if ((r = ssh_add_identity_constrained(agent_fd, private, + comment, lifetime, confirm, skprovider, + dest_constraints, ndest_constraints)) == 0) { + ret = 0; + if (!qflag) { + fprintf(stderr, "Identity added: %s (%s)\n", + filename, comment); + if (lifetime != 0) { + fprintf(stderr, "Lifetime set to %s\n", + fmt_timeframe((time_t)lifetime)); + } + if (confirm != 0) { + fprintf(stderr, "The user must confirm " + "each use of the key\n"); + } } + } else { + fprintf(stderr, "Could not add identity \"%s\": %s\n", + filename, ssh_err(r)); } - } else { - fprintf(stderr, "Could not add identity \"%s\": %s\n", - filename, ssh_err(r)); } /* Skip trying to load the cert if requested */ @@ -412,25 +408,28 @@ add_file(int agent_fd, const char *filename, int key_only, int cert_only, if (!sshkey_equal_public(cert, private)) { error("Certificate %s does not match private key %s", certpath, filename); - sshkey_free(cert); + goto out; + } + + cert_lifetime = lifetime; + if (!Nflag && + (cert_lifetime = check_cert_lifetime(cert, cert_lifetime)) == -1) { + logit("Certificate %s has already expired; ignored", certpath); goto out; } /* Graft with private bits */ if ((r = sshkey_to_certified(private)) != 0) { error_fr(r, "sshkey_to_certified"); - sshkey_free(cert); goto out; } if ((r = sshkey_cert_copy(cert, private)) != 0) { error_fr(r, "sshkey_cert_copy"); - sshkey_free(cert); goto out; } - sshkey_free(cert); - + /* send to agent */ if ((r = ssh_add_identity_constrained(agent_fd, private, comment, - lifetime, confirm, maxsign, skprovider, + cert_lifetime, confirm, skprovider, dest_constraints, ndest_constraints)) != 0) { error_r(r, "Certificate %s (%s) add failed", certpath, private->cert->key_id); @@ -440,9 +439,9 @@ add_file(int agent_fd, const char *filename, int key_only, int cert_only, if (!qflag) { fprintf(stderr, "Certificate added: %s (%s)\n", certpath, private->cert->key_id); - if (lifetime != 0) { - fprintf(stderr, "Lifetime set to %d seconds\n", - lifetime); + if (cert_lifetime != 0) { + fprintf(stderr, "Lifetime set to %s\n", + fmt_timeframe((time_t)cert_lifetime)); } if (confirm != 0) { fprintf(stderr, "The user must confirm each use " @@ -453,6 +452,7 @@ add_file(int agent_fd, const char *filename, int key_only, int cert_only, out: free(certpath); free(comment); + sshkey_free(cert); sshkey_free(private); return ret; @@ -534,7 +534,6 @@ list_identities(int agent_fd, int do_fp) char *fp; int r; struct ssh_identitylist *idlist; - u_int32_t left; size_t i; if ((r = ssh_fetch_identitylist(agent_fd, &idlist)) != 0) { @@ -559,12 +558,7 @@ list_identities(int agent_fd, int do_fp) ssh_err(r)); continue; } - fprintf(stdout, " %s", idlist->comments[i]); - left = sshkey_signatures_left(idlist->keys[i]); - if (left > 0) - fprintf(stdout, - " [signatures left %d]", left); - fprintf(stdout, "\n"); + fprintf(stdout, " %s\n", idlist->comments[i]); } } ssh_free_identitylist(idlist); @@ -622,8 +616,8 @@ load_resident_keys(int agent_fd, const char *skprovider, int qflag, if ((fp = sshkey_fingerprint(key, fingerprint_hash, SSH_FP_DEFAULT)) == NULL) fatal_f("sshkey_fingerprint failed"); - if ((r = ssh_add_identity_constrained(agent_fd, key, "", - lifetime, confirm, maxsign, skprovider, + if ((r = ssh_add_identity_constrained(agent_fd, key, + key->sk_application, lifetime, confirm, skprovider, dest_constraints, ndest_constraints)) != 0) { error("Unable to add key %s %s", sshkey_type(key), fp); @@ -655,7 +649,7 @@ load_resident_keys(int agent_fd, const char *skprovider, int qflag, static int do_file(int agent_fd, int deleting, int key_only, int cert_only, - char *file, int qflag, const char *skprovider, + char *file, int qflag, int Nflag, const char *skprovider, struct dest_constraint **dest_constraints, size_t ndest_constraints) { if (deleting) { @@ -663,29 +657,42 @@ do_file(int agent_fd, int deleting, int key_only, int cert_only, cert_only, qflag) == -1) return -1; } else { - if (add_file(agent_fd, file, key_only, cert_only, qflag, + if (add_file(agent_fd, file, key_only, cert_only, qflag, Nflag, skprovider, dest_constraints, ndest_constraints) == -1) return -1; } return 0; } -/* Append string 's' to a NULL-terminated array of strings */ static void -stringlist_append(char ***listp, const char *s) +free_dest_constraint_hop(struct dest_constraint_hop *dch) { - size_t i = 0; + u_int i; - if (*listp == NULL) - *listp = xcalloc(2, sizeof(**listp)); - else { - for (i = 0; (*listp)[i] != NULL; i++) - ; /* count */ - *listp = xrecallocarray(*listp, i + 1, i + 2, sizeof(**listp)); + if (dch == NULL) + return; + free(dch->user); + free(dch->hostname); + for (i = 0; i < dch->nkeys; i++) + sshkey_free(dch->keys[i]); + free(dch->keys); + free(dch->key_is_ca); +} + +static void +free_dest_constraints(struct dest_constraint **dcs, size_t ndcs) +{ + size_t i; + + for (i = 0; i < ndcs; i++) { + free_dest_constraint_hop(&dcs[i]->from); + free_dest_constraint_hop(&dcs[i]->to); + free(dcs[i]); } - (*listp)[i] = xstrdup(s); + free(dcs); } + static void parse_dest_constraint_hop(const char *s, struct dest_constraint_hop *dch, char **hostkey_files) @@ -794,9 +801,6 @@ usage(void) fprintf(stderr, "usage: ssh-add [-CcDdKkLlqvXx] [-E fingerprint_hash] [-H hostkey_file]\n" " [-h destination_constraint] [-S provider] [-t life]\n" -#ifdef WITH_XMSS -" [-M maxsign] [-m minleft]\n" -#endif " [file ...]\n" " ssh-add -s pkcs11 [-Cv] [certificate ...]\n" " ssh-add -e pkcs11\n" @@ -814,12 +818,12 @@ main(int argc, char **argv) char **dest_constraint_strings = NULL, **hostkey_files = NULL; int r, i, ch, deleting = 0, ret = 0, key_only = 0, cert_only = 0; int do_download = 0, xflag = 0, lflag = 0, Dflag = 0; - int qflag = 0, Tflag = 0; + int Qflag = 0, qflag = 0, Tflag = 0, Nflag = 0; SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; LogLevel log_level = SYSLOG_LEVEL_INFO; struct sshkey *k, **certs = NULL; struct dest_constraint **dest_constraints = NULL; - size_t ndest_constraints = 0, ncerts = 0; + size_t n, ndest_constraints = 0, ncerts = 0; /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); @@ -846,7 +850,7 @@ main(int argc, char **argv) skprovider = getenv("SSH_SK_PROVIDER"); - while ((ch = getopt(argc, argv, "vkKlLCcdDTxXE:e:h:H:M:m:qs:S:t:")) != -1) { + while ((ch = getopt(argc, argv, "vkKlLNCcdDTxXE:e:h:H:M:m:Qqs:S:t:")) != -1) { switch (ch) { case 'v': if (log_level == SYSLOG_LEVEL_INFO) @@ -854,6 +858,9 @@ main(int argc, char **argv) else if (log_level < SYSLOG_LEVEL_DEBUG3) log_level++; break; + case 'N': + Nflag = 1; + break; case 'E': fingerprint_hash = ssh_digest_alg_by_name(optarg); if (fingerprint_hash == -1) @@ -890,20 +897,8 @@ main(int argc, char **argv) confirm = 1; break; case 'm': - minleft = (u_int)strtonum(optarg, 1, UINT_MAX, NULL); - if (minleft == 0) { - usage(); - ret = 1; - goto done; - } - break; case 'M': - maxsign = (u_int)strtonum(optarg, 1, UINT_MAX, NULL); - if (maxsign == 0) { - usage(); - ret = 1; - goto done; - } + /* deprecated */ break; case 'd': deleting = 1; @@ -932,6 +927,9 @@ main(int argc, char **argv) case 'q': qflag = 1; break; + case 'Q': + Qflag = 1; + break; case 'T': Tflag = 1; break; @@ -943,7 +941,7 @@ main(int argc, char **argv) } log_init(__progname, log_level, log_facility, 1); - if ((xflag != 0) + (lflag != 0) + (Dflag != 0) > 1) + if ((xflag != 0) + (lflag != 0) + (Dflag != 0) + (Qflag != 0) > 1) fatal("Invalid combination of actions"); else if (xflag) { if (lock_agent(agent_fd, xflag == 'x' ? 1 : 0) == -1) @@ -957,6 +955,10 @@ main(int argc, char **argv) if (delete_all(agent_fd, qflag) == -1) ret = 1; goto done; + } else if (Qflag) { + if (query_exts(agent_fd) == -1) + ret = 1; + goto done; } #ifdef ENABLE_SK_INTERNAL @@ -1003,6 +1005,9 @@ main(int argc, char **argv) dest_constraints, ndest_constraints, certs, ncerts) == -1) ret = 1; + for (n = 0; n < ncerts; n++) + sshkey_free(certs[n]); + free(certs); goto done; } if (do_download) { @@ -1032,7 +1037,7 @@ main(int argc, char **argv) if (stat(buf, &st) == -1) continue; if (do_file(agent_fd, deleting, key_only, cert_only, - buf, qflag, skprovider, + buf, qflag, Nflag, skprovider, dest_constraints, ndest_constraints) == -1) ret = 1; else @@ -1043,13 +1048,16 @@ main(int argc, char **argv) } else { for (i = 0; i < argc; i++) { if (do_file(agent_fd, deleting, key_only, cert_only, - argv[i], qflag, skprovider, + argv[i], qflag, Nflag, skprovider, dest_constraints, ndest_constraints) == -1) ret = 1; } } done: clear_pass(); + stringlist_free(hostkey_files); + stringlist_free(dest_constraint_strings); + free_dest_constraints(dest_constraints, ndest_constraints); ssh_close_authentication_socket(agent_fd); return ret; } diff --git a/ssh-agent.0 b/ssh-agent.0 index 33971e9..9abedc2 100644 --- a/ssh-agent.0 +++ b/ssh-agent.0 @@ -4,11 +4,12 @@ NAME ssh-agent M-bM-^@M-^S OpenSSH authentication agent SYNOPSIS - ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash] + ssh-agent [-c | -s] [-DdTU] [-a bind_address] [-E fingerprint_hash] [-O option] [-P allowed_providers] [-t life] - ssh-agent [-a bind_address] [-E fingerprint_hash] [-O option] + ssh-agent [-TU] [-a bind_address] [-E fingerprint_hash] [-O option] [-P allowed_providers] [-t life] command [arg ...] ssh-agent [-c | -s] -k + ssh-agent -u DESCRIPTION ssh-agent is a program to hold private keys used for public key @@ -19,11 +20,12 @@ DESCRIPTION The options are as follows: -a bind_address - Bind the agent to the UNIX-domain socket bind_address. The - default is $TMPDIR/ssh-XXXXXXXXXX/agent.. + Bind the agent to the Unix-domain socket bind_address. The + default is to create a socket at a random path matching + $HOME/.ssh/agent/s.*. - -c Generate C-shell commands on stdout. This is the default if - SHELL looks like it's a csh style of shell. + -c Generate C-shell commands on standard output. This is the + default if SHELL looks like it's a csh style of shell. -D Foreground mode. When this option is specified, ssh-agent will not fork. @@ -40,8 +42,8 @@ DESCRIPTION variable). -O option - Specify an option when starting ssh-agent. Currently two options - are supported: allow-remote-pkcs11 and no-restrict-websafe. + Specify an option when starting ssh-agent. The supported options + are: allow-remote-pkcs11, no-restrict-websafe and websafe-allow. The allow-remote-pkcs11 option allows clients of a forwarded ssh-agent to load PKCS#11 or FIDO provider libraries. By default @@ -54,22 +56,37 @@ DESCRIPTION signatures using FIDO keys that might be web authentication requests. By default, ssh-agent refuses signature requests for FIDO keys where the key application string does not start with - M-bM-^@M-^\ssh:M-bM-^@M-^] and when the data to be signed does not appear to be a - ssh(1) user authentication request or a ssh-keygen(1) signature. + M-bM-^@M-^\ssh:M-bM-^@M-^] and when the data to be signed does not appear to be an + ssh(1) user authentication request or an ssh-keygen(1) signature. The default behaviour prevents forwarded access to a FIDO key from also implicitly forwarding the ability to authenticate to websites. + Alternately the websafe-allow option allows specifying a pattern- + list of key application strings to replace the default + application allow-list, for example: + M-bM-^@M-^\websafe-allow=ssh:*,example.org,*.example.comM-bM-^@M-^] + + See PATTERNS in ssh_config(5) for a description of pattern-list + syntax. + -P allowed_providers Specify a pattern-list of acceptable paths for PKCS#11 provider and FIDO authenticator middleware shared libraries that may be used with the -S or -s options to ssh-add(1). Libraries that do - not match the pattern list will be refused. See PATTERNS in - ssh_config(5) for a description of pattern-list syntax. The - default list is M-bM-^@M-^\usr/lib*/*,/usr/local/lib*/*M-bM-^@M-^]. + not match the pattern list will be refused. The default list is + M-bM-^@M-^\/usr/lib*/*,/usr/local/lib*/*M-bM-^@M-^]. + + See PATTERNS in ssh_config(5) for a description of pattern-list + syntax. + + -s Generate Bourne shell commands on standard output. This is the + default if SHELL does not look like it's a csh style of shell. - -s Generate Bourne shell commands on stdout. This is the default if - SHELL does not look like it's a csh style of shell. + -T Bind the agent socket in a randomised subdirectory of the form + $TMPDIR/ssh-XXXXXXXXXX/agent., instead of the default + behaviour of using a randomised name matching + $HOME/.ssh/agent/s.*. -t life Set a default value for the maximum lifetime of identities added @@ -78,12 +95,20 @@ DESCRIPTION for an identity with ssh-add(1) overrides this value. Without this option the default maximum lifetime is forever. + -U Instructs ssh-agent not to clean up stale agent sockets under + $HOME/.ssh/agent/. + + -u Instructs ssh-agent to only clean up stale agent sockets under + $HOME/.ssh/agent/ and then exit immediately. If this option is + given twice, ssh-agent will delete stale agent sockets regardless + of the host name that created them. + command [arg ...] If a command (and optional arguments) is given, this is executed as a subprocess of the agent. The agent exits automatically when the command given on the command line terminates. - There are two main ways to get an agent set up. The first is at the + There are three main ways to get an agent set up. The first is at the start of an X session, where all other windows or programs are started as children of the ssh-agent program. The agent starts a command under which its environment variables are exported, for example ssh-agent xterm @@ -94,8 +119,18 @@ DESCRIPTION variables, which in turn can be evaluated in the calling shell, for example eval `ssh-agent -s`. - In both cases, ssh(1) looks at these environment variables and uses them - to establish a connection to the agent. + In both of these cases, ssh(1) looks at these environment variables and + uses them to establish a connection to the agent. + + The third way to run ssh-agent is via socket activation from a + supervising process, such as systemd. In this mode, the supervising + process creates the listening socket and is responsible for starting + ssh-agent as needed, and also for communicating the location of the + socket listener to other programs in the user's session. Socket + activation is used when ssh-agent is started with either of the -d or -D + flags, no socket listening address specified by the -a flag, and both the + LISTEN_FDS and LISTEN_PID environment variables correctly supplied by the + supervising process. The agent initially does not have any private keys. Keys are added using ssh-add(1) or by ssh(1) when AddKeysToAgent is set in ssh_config(5). @@ -111,18 +146,20 @@ DESCRIPTION the result is returned to the requester, allowing the user access to their identities anywhere in the network in a secure fashion. + ssh-agent will delete all keys it has loaded upon receiving SIGUSR1. + ENVIRONMENT SSH_AGENT_PID When ssh-agent starts, it stores the name of the agent's process ID (PID) in this variable. - SSH_AUTH_SOCK When ssh-agent starts, it creates a UNIX-domain socket and + SSH_AUTH_SOCK When ssh-agent starts, it creates a Unix-domain socket and stores its pathname in this variable. It is accessible only to the current user, but is easily abused by root or another instance of the same user. FILES - $TMPDIR/ssh-XXXXXXXXXX/agent. - UNIX-domain sockets used to contain the connection to the + $HOME/.ssh/agent/s.* + Unix-domain sockets used to contain the connection to the authentication agent. These sockets should only be readable by the owner. The sockets should get automatically removed when the agent exits. @@ -137,4 +174,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 7.6 August 10, 2023 OpenBSD 7.6 +OpenBSD 7.8 October 4, 2025 SSH-AGENT(1) diff --git a/ssh-agent.1 b/ssh-agent.1 index 0b93d03..016f7e0 100644 --- a/ssh-agent.1 +++ b/ssh-agent.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-agent.1,v 1.79 2023/08/10 14:37:32 naddy Exp $ +.\" $OpenBSD: ssh-agent.1,v 1.86 2025/10/04 21:41:35 naddy Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: August 10 2023 $ +.Dd $Mdocdate: October 4 2025 $ .Dt SSH-AGENT 1 .Os .Sh NAME @@ -43,13 +43,14 @@ .Sh SYNOPSIS .Nm ssh-agent .Op Fl c | s -.Op Fl \&Dd +.Op Fl \&DdTU .Op Fl a Ar bind_address .Op Fl E Ar fingerprint_hash .Op Fl O Ar option .Op Fl P Ar allowed_providers .Op Fl t Ar life .Nm ssh-agent +.Op Fl TU .Op Fl a Ar bind_address .Op Fl E Ar fingerprint_hash .Op Fl O Ar option @@ -59,6 +60,8 @@ .Nm ssh-agent .Op Fl c | s .Fl k +.Nm ssh-agent +.Fl u .Sh DESCRIPTION .Nm is a program to hold private keys used for public key authentication. @@ -74,11 +77,10 @@ Bind the agent to the .Ux Ns -domain socket .Ar bind_address . -The default is -.Pa $TMPDIR/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt . +The default is to create a socket at a random path matching +.Pa $HOME/.ssh/agent/s.* . .It Fl c -Generate C-shell commands on -.Dv stdout . +Generate C-shell commands on standard output. This is the default if .Ev SHELL looks like it's a csh style of shell. @@ -107,10 +109,11 @@ environment variable). .It Fl O Ar option Specify an option when starting .Nm . -Currently two options are supported: -.Cm allow-remote-pkcs11 +The supported options are: +.Cm allow-remote-pkcs11 , +.Cm no-restrict-websafe and -.Cm no-restrict-websafe . +.Cm websafe-allow . .Pp The .Cm allow-remote-pkcs11 @@ -136,13 +139,23 @@ By default, refuses signature requests for FIDO keys where the key application string does not start with .Dq ssh: -and when the data to be signed does not appear to be a +and when the data to be signed does not appear to be an .Xr ssh 1 -user authentication request or a +user authentication request or an .Xr ssh-keygen 1 signature. The default behaviour prevents forwarded access to a FIDO key from also implicitly forwarding the ability to authenticate to websites. +.Pp +Alternately the +.Cm websafe-allow +option allows specifying a pattern-list of key application strings to +replace the default application allow-list, for example: +.Dq websafe-allow=ssh:*,example.org,*.example.com +.Pp +See PATTERNS in +.Xr ssh_config 5 +for a description of pattern-list syntax. .It Fl P Ar allowed_providers Specify a pattern-list of acceptable paths for PKCS#11 provider and FIDO authenticator middleware shared libraries that may be used with the @@ -152,17 +165,22 @@ or options to .Xr ssh-add 1 . Libraries that do not match the pattern list will be refused. +The default list is +.Dq /usr/lib*/*,/usr/local/lib*/* . +.Pp See PATTERNS in .Xr ssh_config 5 for a description of pattern-list syntax. -The default list is -.Dq usr/lib*/*,/usr/local/lib*/* . .It Fl s -Generate Bourne shell commands on -.Dv stdout . +Generate Bourne shell commands on standard output. This is the default if .Ev SHELL does not look like it's a csh style of shell. +.It Fl T +Bind the agent socket in a randomised subdirectory of the form +.Pa $TMPDIR/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt , +instead of the default behaviour of using a randomised name matching +.Pa $HOME/.ssh/agent/s.* . .It Fl t Ar life Set a default value for the maximum lifetime of identities added to the agent. The lifetime may be specified in seconds or in a time format specified in @@ -171,6 +189,20 @@ A lifetime specified for an identity with .Xr ssh-add 1 overrides this value. Without this option the default maximum lifetime is forever. +.It Fl U +Instructs +.Nm +not to clean up stale agent sockets under +.Pa $HOME/.ssh/agent/ . +.It Fl u +Instructs +.Nm +to only clean up stale agent sockets under +.Pa $HOME/.ssh/agent/ +and then exit immediately. +If this option is given twice, +.Nm +will delete stale agent sockets regardless of the host name that created them. .It Ar command Op Ar arg ... If a command (and optional arguments) is given, this is executed as a subprocess of the agent. @@ -178,7 +210,7 @@ The agent exits automatically when the command given on the command line terminates. .El .Pp -There are two main ways to get an agent set up. +There are three main ways to get an agent set up. The first is at the start of an X session, where all other windows or programs are started as children of the .Nm @@ -196,11 +228,33 @@ it prints the shell commands required to set its environment variables, which in turn can be evaluated in the calling shell, for example .Cm eval `ssh-agent -s` . .Pp -In both cases, +In both of these cases, .Xr ssh 1 looks at these environment variables and uses them to establish a connection to the agent. .Pp +The third way to run +.Nm +is via socket activation from a supervising process, such as systemd. +In this mode, the supervising process creates the listening socket and +is responsible for starting +.Nm +as needed, and also for communicating the location of the socket listener +to other programs in the user's session. +Socket activation is used when +.Nm +is started with either of the +.Fl d +or +.Fl D +flags, no socket listening address specified by the +.Fl a +flag, and both the +.Ev LISTEN_FDS +and +.Ev LISTEN_PID +environment variables correctly supplied by the supervising process. +.Pp The agent initially does not have any private keys. Keys are added using .Xr ssh-add 1 @@ -233,6 +287,10 @@ the connection to the agent is forwarded over SSH remote connections and the result is returned to the requester, allowing the user access to their identities anywhere in the network in a secure fashion. +.Pp +.Nm +will delete all keys it has loaded upon receiving +.Dv SIGUSR1 . .Sh ENVIRONMENT .Bl -tag -width "SSH_AGENT_PID" .It Ev SSH_AGENT_PID @@ -250,7 +308,7 @@ but is easily abused by root or another instance of the same user. .El .Sh FILES .Bl -tag -width Ds -.It Pa $TMPDIR/ssh-XXXXXXXXXX/agent. +.It Pa $HOME/.ssh/agent/s.* .Ux Ns -domain sockets used to contain the connection to the authentication agent. These sockets should only be readable by the owner. diff --git a/ssh-agent.c b/ssh-agent.c index fc8e459..c73abd1 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-agent.c,v 1.306 2024/03/09 05:12:13 djm Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.324 2026/03/10 07:27:14 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -37,17 +37,13 @@ #include "includes.h" #include +#include +#include #include -#include #include +#include +#include #include -#ifdef HAVE_SYS_TIME_H -# include -#endif -#ifdef HAVE_SYS_UN_H -# include -#endif -#include "openbsd-compat/sys-queue.h" #ifdef WITH_OPENSSL #include @@ -56,23 +52,17 @@ #include #include -#include -#ifdef HAVE_PATHS_H -# include -#endif -#ifdef HAVE_POLL_H -# include -#endif +#include +#include #include -#include -#include #include -#include +#include #include +#include +#include +#include #include -#ifdef HAVE_UTIL_H -# include -#endif +#include #include "xmalloc.h" #include "ssh.h" @@ -94,6 +84,9 @@ #ifndef DEFAULT_ALLOWED_PROVIDERS # define DEFAULT_ALLOWED_PROVIDERS "/usr/lib*/*,/usr/local/lib*/*" #endif +#ifndef DEFAULT_WEBSAFE_ALLOWLIST +# define DEFAULT_WEBSAFE_ALLOWLIST "ssh:*" +#endif /* Maximum accepted message length */ #define AGENT_MAX_LEN (256*1024) @@ -162,14 +155,15 @@ int max_fd = 0; pid_t parent_pid = -1; time_t parent_alive_interval = 0; -sig_atomic_t signalled = 0; +static sig_atomic_t signalled_exit; +static sig_atomic_t signalled_keydrop; /* pid of process for which cleanup_socket is applicable */ pid_t cleanup_pid = 0; /* pathname and directory for AUTH_SOCKET */ -char socket_name[PATH_MAX]; -char socket_dir[PATH_MAX]; +static char *socket_name; +static char socket_dir[PATH_MAX]; /* Pattern-list of allowed PKCS#11/Security key paths */ static char *allowed_providers; @@ -197,6 +191,7 @@ static int fingerprint_hash = SSH_FP_HASH_DEFAULT; /* Refuse signing of non-SSH messages for web-origin FIDO keys */ static int restrict_websafe = 1; +static char *websafe_allowlist; static void close_socket(SocketEntry *e) @@ -397,7 +392,7 @@ match_key_hop(const char *tag, const struct sshkey *key, return -1; /* shouldn't happen */ if (!sshkey_equal(key->cert->signature_key, dch->keys[i])) continue; - if (sshkey_cert_check_host(key, hostname, 1, + if (sshkey_cert_check_host(key, hostname, SSH_ALLOWED_CA_SIGALGS, &reason) != 0) { debug_f("cert %s / hostname %s rejected: %s", key->cert->key_id, hostname, reason); @@ -603,16 +598,22 @@ confirm_key(Identity *id, const char *extra) } static void -send_status(SocketEntry *e, int success) +send_status_generic(SocketEntry *e, u_int code) { int r; if ((r = sshbuf_put_u32(e->output, 1)) != 0 || - (r = sshbuf_put_u8(e->output, success ? - SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE)) != 0) + (r = sshbuf_put_u8(e->output, code)) != 0) fatal_fr(r, "compose"); } +static void +send_status(SocketEntry *e, int success) +{ + return send_status_generic(e, + success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); +} + /* send list of supported public keys to 'client' */ static void process_request_identities(SocketEntry *e) @@ -639,8 +640,7 @@ process_request_identities(SocketEntry *e) /* identity not visible, don't include in response */ if (identity_permitted(id, e, NULL, NULL, NULL) != 0) continue; - if ((r = sshkey_puts_opts(id->key, keys, - SSHKEY_SERIALIZE_INFO)) != 0 || + if ((r = sshkey_puts(id->key, keys)) != 0 || (r = sshbuf_put_cstring(keys, id->comment)) != 0) { error_fr(r, "compose key/comment"); continue; @@ -924,7 +924,8 @@ process_sign_request2(SocketEntry *e) } if (sshkey_is_sk(id->key)) { if (restrict_websafe && - strncmp(id->key->sk_application, "ssh:", 4) != 0 && + match_pattern_list(id->key->sk_application, + websafe_allowlist, 0) != 1 && !check_websafe_message_contents(key, data)) { /* error already logged */ goto send; @@ -1021,7 +1022,7 @@ process_remove_identity(SocketEntry *e) } static void -process_remove_all_identities(SocketEntry *e) +remove_all_identities(void) { Identity *id; @@ -1035,6 +1036,12 @@ process_remove_all_identities(SocketEntry *e) /* Mark that there are no identities. */ idtab->nentries = 0; +} + +static void +process_remove_all_identities(SocketEntry *e) +{ + remove_all_identities(); /* Send success. */ send_status(e, 1); @@ -1280,7 +1287,7 @@ parse_key_constraints(struct sshbuf *m, struct sshkey *k, time_t *deathp, { u_char ctype; int r; - u_int seconds, maxsign = 0; + u_int seconds; while (sshbuf_len(m)) { if ((r = sshbuf_get_u8(m, &ctype)) != 0) { @@ -1309,26 +1316,6 @@ parse_key_constraints(struct sshbuf *m, struct sshkey *k, time_t *deathp, } *confirmp = 1; break; - case SSH_AGENT_CONSTRAIN_MAXSIGN: - if (k == NULL) { - error_f("maxsign not valid here"); - r = SSH_ERR_INVALID_FORMAT; - goto out; - } - if (maxsign != 0) { - error_f("maxsign already set"); - r = SSH_ERR_INVALID_FORMAT; - goto out; - } - if ((r = sshbuf_get_u32(m, &maxsign)) != 0) { - error_fr(r, "parse maxsign constraint"); - goto out; - } - if ((r = sshkey_enable_maxsign(k, maxsign)) != 0) { - error_fr(r, "enable maxsign"); - goto out; - } - break; case SSH_AGENT_CONSTRAIN_EXTENSION: if ((r = parse_key_constraint_extension(m, sk_providerp, dcsp, ndcsp, @@ -1707,6 +1694,10 @@ process_ext_session_bind(SocketEntry *e) error_fr(r, "parse"); goto out; } + if (sshbuf_len(sid) > AGENT_MAX_SID_LEN) { + error_f("session ID too long"); + goto out; + } if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT, SSH_FP_DEFAULT)) == NULL) fatal_f("fingerprint failed"); @@ -1771,6 +1762,26 @@ process_ext_session_bind(SocketEntry *e) return r == 0 ? 1 : 0; } +static int +process_ext_query(SocketEntry *e) +{ + int r; + struct sshbuf *msg = NULL; + + debug2_f("entering"); + if ((msg = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + if ((r = sshbuf_put_u8(msg, SSH_AGENT_EXTENSION_RESPONSE)) != 0 || + (r = sshbuf_put_cstring(msg, "query")) != 0 || + /* string[] supported extension types */ + (r = sshbuf_put_cstring(msg, "session-bind@openssh.com")) != 0) + fatal_fr(r, "compose"); + if ((r = sshbuf_put_stringb(e->output, msg)) != 0) + fatal_fr(r, "enqueue"); + sshbuf_free(msg); + return 1; +} + static void process_extension(SocketEntry *e) { @@ -1780,16 +1791,26 @@ process_extension(SocketEntry *e) debug2_f("entering"); if ((r = sshbuf_get_cstring(e->request, &name, NULL)) != 0) { error_fr(r, "parse"); - goto send; + send_status(e, 0); + return; } - if (strcmp(name, "session-bind@openssh.com") == 0) + + if (strcmp(name, "query") == 0) + success = process_ext_query(e); + else if (strcmp(name, "session-bind@openssh.com") == 0) success = process_ext_session_bind(e); - else + else { debug_f("unsupported extension \"%s\"", name); + free(name); + send_status(e, 0); + return; + } free(name); -send: - send_status(e, success); + /* Agent failures are signalled with a different error code */ + send_status_generic(e, + success ? SSH_AGENT_SUCCESS : SSH_AGENT_EXTENSION_FAILURE); } + /* * dispatch incoming message. * returns 1 on success, 0 for incomplete messages or -1 on error. @@ -2146,8 +2167,11 @@ cleanup_socket(void) if (cleanup_pid != 0 && getpid() != cleanup_pid) return; debug_f("cleanup"); - if (socket_name[0]) + if (socket_name != NULL) { unlink(socket_name); + free(socket_name); + socket_name = NULL; + } if (socket_dir[0]) rmdir(socket_dir); } @@ -2165,7 +2189,13 @@ cleanup_exit(int i) static void cleanup_handler(int sig) { - signalled = sig; + signalled_exit = sig; +} + +static void +keydrop_handler(int sig) +{ + signalled_keydrop = sig; } static void @@ -2186,27 +2216,32 @@ static void usage(void) { fprintf(stderr, - "usage: ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash]\n" + "usage: ssh-agent [-c | -s] [-DdTU] [-a bind_address] [-E fingerprint_hash]\n" " [-O option] [-P allowed_providers] [-t life]\n" - " ssh-agent [-a bind_address] [-E fingerprint_hash] [-O option]\n" + " ssh-agent [-TU] [-a bind_address] [-E fingerprint_hash] [-O option]\n" " [-P allowed_providers] [-t life] command [arg ...]\n" - " ssh-agent [-c | -s] -k\n"); + " ssh-agent [-c | -s] -k\n" + " ssh-agent -u\n"); exit(1); } int main(int ac, char **av) { - int c_flag = 0, d_flag = 0, D_flag = 0, k_flag = 0, s_flag = 0; - int sock, ch, result, saved_errno; - char *shell, *format, *pidstr, *agentsocket = NULL; + int c_flag = 0, d_flag = 0, D_flag = 0, k_flag = 0; + int s_flag = 0, T_flag = 0, u_flag = 0, U_flag = 0; + int sock = -1, ch, result, saved_errno; + pid_t pid; + char *homedir = NULL, *shell, *format, *pidstr, *agentsocket = NULL; + char *cp, pidstrbuf[1 + 3 * sizeof pid]; + char *fdstr; + const char *errstr = NULL; + const char *ccp; #ifdef HAVE_SETRLIMIT struct rlimit rlim; #endif extern int optind; extern char *optarg; - pid_t pid; - char pidstrbuf[1 + 3 * sizeof pid]; size_t len; mode_t prev_mask; struct timespec timeout; @@ -2214,6 +2249,7 @@ main(int ac, char **av) size_t npfd = 0; u_int maxfds; sigset_t nsigset, osigset; + int socket_activated = 0; /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); @@ -2232,7 +2268,7 @@ main(int ac, char **av) __progname = ssh_get_progname(av[0]); seed_rng(); - while ((ch = getopt(ac, av, "cDdksE:a:O:P:t:")) != -1) { + while ((ch = getopt(ac, av, "cDdksTuUE:a:O:P:t:")) != -1) { switch (ch) { case 'E': fingerprint_hash = ssh_digest_alg_by_name(optarg); @@ -2252,7 +2288,12 @@ main(int ac, char **av) restrict_websafe = 0; else if (strcmp(optarg, "allow-remote-pkcs11") == 0) remote_add_provider = 1; - else + else if ((ccp = strprefix(optarg, + "websafe-allow=", 0)) != NULL) { + if (websafe_allowlist != NULL) + fatal("websafe-allow already set"); + websafe_allowlist = xstrdup(ccp); + } else fatal("Unknown -O option"); break; case 'P': @@ -2284,6 +2325,15 @@ main(int ac, char **av) usage(); } break; + case 'T': + T_flag++; + break; + case 'u': + u_flag++; + break; + case 'U': + U_flag++; + break; default: usage(); } @@ -2291,11 +2341,18 @@ main(int ac, char **av) ac -= optind; av += optind; - if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || D_flag)) + if (ac > 0 && + (c_flag || k_flag || s_flag || d_flag || D_flag || u_flag)) usage(); + log_init(__progname, + d_flag ? SYSLOG_LEVEL_DEBUG3 : SYSLOG_LEVEL_INFO, + SYSLOG_FACILITY_AUTH, 1); + if (allowed_providers == NULL) allowed_providers = xstrdup(DEFAULT_ALLOWED_PROVIDERS); + if (websafe_allowlist == NULL) + websafe_allowlist = xstrdup(DEFAULT_WEBSAFE_ALLOWLIST); if (ac == 0 && !c_flag && !s_flag) { shell = getenv("SHELL"); @@ -2304,8 +2361,6 @@ main(int ac, char **av) c_flag = 1; } if (k_flag) { - const char *errstr = NULL; - pidstr = getenv(SSH_AGENTPID_ENV_NAME); if (pidstr == NULL) { fprintf(stderr, "%s not set, cannot kill agent\n", @@ -2329,6 +2384,14 @@ main(int ac, char **av) printf("echo Agent pid %ld killed;\n", (long)pid); exit(0); } + if (u_flag) { + if ((homedir = get_homedir()) == NULL) + fatal("Couldn't determine home directory"); + agent_cleanup_stale(homedir, u_flag > 1); + printf("Deleted stale agent sockets in ~/%s\n", + _PATH_SSH_AGENT_SOCKET_DIR); + exit(0); + } /* * Minimum file descriptors: @@ -2343,33 +2406,79 @@ main(int ac, char **av) parent_pid = getpid(); - if (agentsocket == NULL) { - /* Create private directory for agent socket */ - mktemp_proto(socket_dir, sizeof(socket_dir)); - if (mkdtemp(socket_dir) == NULL) { - perror("mkdtemp: private socket dir"); - exit(1); + /* Has the socket been provided via socket activation? */ + if (agentsocket == NULL && ac == 0 && (d_flag || D_flag) && + (pidstr = getenv("LISTEN_PID")) != NULL && + (fdstr = getenv("LISTEN_FDS")) != NULL) { + if (strcmp(fdstr, "1") != 0) { + fatal("unexpected LISTEN_FDS contents " + "(want: \"1\" got\"%s\"", fdstr); } - snprintf(socket_name, sizeof socket_name, "%s/agent.%ld", socket_dir, - (long)parent_pid); - } else { - /* Try to use specified agent socket */ - socket_dir[0] = '\0'; - strlcpy(socket_name, agentsocket, sizeof socket_name); + if (fcntl(3, F_GETFL) == -1) + fatal("LISTEN_FDS set but fd 3 unavailable"); + pid = (int)strtonum(pidstr, 1, INT_MAX, &errstr); + if (errstr != NULL) + fatal("invalid LISTEN_PID: %s", errstr); + if (pid != getpid()) + fatal("bad LISTEN_PID: %d vs pid %d", pid, getpid()); + debug("using socket activation on fd=3"); + sock = 3; + socket_activated = 1; + } + + if (sock == -1 && agentsocket == NULL && !T_flag) { + /* Default case: ~/.ssh/agent/[socket] */ + if ((homedir = get_homedir()) == NULL) + fatal("Couldn't determine home directory"); + if (!U_flag) + agent_cleanup_stale(homedir, 0); + if (agent_listener(homedir, "agent", &sock, &socket_name) != 0) + fatal_f("Couldn't prepare agent socket"); + free(homedir); + } else if (sock == -1) { + if (T_flag) { + /* + * Create private directory for agent socket + * in $TMPDIR. + */ + mktemp_proto(socket_dir, sizeof(socket_dir)); + if (mkdtemp(socket_dir) == NULL) { + perror("mkdtemp: private socket dir"); + exit(1); + } + xasprintf(&socket_name, "%s/agent.%ld", + socket_dir, (long)parent_pid); + } else { + /* Try to use specified agent socket */ + socket_dir[0] = '\0'; + socket_name = xstrdup(agentsocket); + } + /* Listen on socket */ + prev_mask = umask(0177); + if ((sock = unix_listener(socket_name, + SSH_LISTEN_BACKLOG, 0)) < 0) { + *socket_name = '\0'; /* Don't unlink existing file */ + cleanup_exit(1); + } + umask(prev_mask); } + closefrom(sock == -1 ? STDERR_FILENO + 1 : sock + 1); + /* * Create socket early so it will exist before command gets run from * the parent. */ - prev_mask = umask(0177); - sock = unix_listener(socket_name, SSH_LISTEN_BACKLOG, 0); - if (sock < 0) { - /* XXX - unix_listener() calls error() not perror() */ - *socket_name = '\0'; /* Don't unlink any existing file */ - cleanup_exit(1); + if (sock == -1) { + prev_mask = umask(0177); + sock = unix_listener(socket_name, SSH_LISTEN_BACKLOG, 0); + if (sock < 0) { + /* XXX - unix_listener() calls error() not perror() */ + *socket_name = '\0'; /* Don't unlink existing file */ + cleanup_exit(1); + } + umask(prev_mask); } - umask(prev_mask); /* * Fork, and have the parent execute the command, if any, or present @@ -2379,11 +2488,16 @@ main(int ac, char **av) log_init(__progname, d_flag ? SYSLOG_LEVEL_DEBUG3 : SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_AUTH, 1); - format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n"; - printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name, - SSH_AUTHSOCKET_ENV_NAME); - printf("echo Agent pid %ld;\n", (long)parent_pid); - fflush(stdout); + if (socket_name != NULL) { + cp = argv_assemble(1, &socket_name); + format = c_flag ? + "setenv %s %s;\n" : "%s=%s; export %s;\n"; + printf(format, SSH_AUTHSOCKET_ENV_NAME, cp, + SSH_AUTHSOCKET_ENV_NAME); + free(cp); + printf("echo Agent pid %ld;\n", (long)parent_pid); + fflush(stdout); + } goto skip; } pid = fork(); @@ -2396,10 +2510,12 @@ main(int ac, char **av) snprintf(pidstrbuf, sizeof pidstrbuf, "%ld", (long)pid); if (ac == 0) { format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n"; - printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name, + cp = argv_assemble(1, &socket_name); + printf(format, SSH_AUTHSOCKET_ENV_NAME, cp, SSH_AUTHSOCKET_ENV_NAME); printf(format, SSH_AGENTPID_ENV_NAME, pidstrbuf, SSH_AGENTPID_ENV_NAME); + free(cp); printf("echo Agent pid %ld;\n", (long)pid); exit(0); } @@ -2448,21 +2564,46 @@ main(int ac, char **av) ssh_signal(SIGINT, (d_flag | D_flag) ? cleanup_handler : SIG_IGN); ssh_signal(SIGHUP, cleanup_handler); ssh_signal(SIGTERM, cleanup_handler); + ssh_signal(SIGUSR1, keydrop_handler); sigemptyset(&nsigset); sigaddset(&nsigset, SIGINT); sigaddset(&nsigset, SIGHUP); sigaddset(&nsigset, SIGTERM); - - if (pledge("stdio rpath cpath unix id proc exec", NULL) == -1) + sigaddset(&nsigset, SIGUSR1); + + if (unveil("/", "r") == -1) + fatal("%s: unveil /: %s", __progname, strerror(errno)); + if ((ccp = getenv("SSH_SK_HELPER")) == NULL || *ccp == '\0') + ccp = _PATH_SSH_SK_HELPER; + if (unveil(ccp, "x") == -1) + fatal("%s: unveil %s: %s", __progname, ccp, strerror(errno)); + if ((ccp = getenv("SSH_PKCS11_HELPER")) == NULL || *ccp == '\0') + ccp = _PATH_SSH_PKCS11_HELPER; + if (unveil(ccp, "x") == -1) + fatal("%s: unveil %s: %s", __progname, ccp, strerror(errno)); + if ((ccp = getenv("SSH_ASKPASS")) == NULL || *ccp == '\0') + ccp = _PATH_SSH_ASKPASS_DEFAULT; + if (unveil(ccp, "x") == -1) + fatal("%s: unveil %s: %s", __progname, ccp, strerror(errno)); + if (unveil("/dev/null", "rw") == -1) + fatal("%s: unveil /dev/null: %s", __progname, strerror(errno)); + if (pledge("stdio rpath cpath wpath unix id proc exec", NULL) == -1) fatal("%s: pledge: %s", __progname, strerror(errno)); platform_pledge_agent(); while (1) { sigprocmask(SIG_BLOCK, &nsigset, &osigset); - if (signalled != 0) { - logit("exiting on signal %d", (int)signalled); - cleanup_exit(2); + if (signalled_exit != 0) { + logit("exiting on signal %d", (int)signalled_exit); + cleanup_exit((signalled_exit == SIGTERM && + socket_activated) ? 0 : 2); + } + if (signalled_keydrop) { + logit("signal %d received; removing all keys", + (int)signalled_keydrop); + remove_all_identities(); + signalled_keydrop = 0; } ptimeout_init(&timeout); prepare_poll(&pfd, &npfd, &timeout, maxfds); diff --git a/ssh-dss.c b/ssh-dss.c deleted file mode 100644 index aea6613..0000000 --- a/ssh-dss.c +++ /dev/null @@ -1,457 +0,0 @@ -/* $OpenBSD: ssh-dss.c,v 1.50 2024/01/11 01:45:36 djm Exp $ */ -/* - * Copyright (c) 2000 Markus Friedl. 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" - -#if defined(WITH_OPENSSL) && defined(WITH_DSA) - -#include - -#include -#include -#include - -#include -#include - -#include "sshbuf.h" -#include "ssherr.h" -#include "digest.h" -#define SSHKEY_INTERNAL -#include "sshkey.h" - -#include "openbsd-compat/openssl-compat.h" - -#define INTBLOB_LEN 20 -#define SIGBLOB_LEN (2*INTBLOB_LEN) - -static u_int -ssh_dss_size(const struct sshkey *key) -{ - const BIGNUM *dsa_p; - - if (key->dsa == NULL) - return 0; - DSA_get0_pqg(key->dsa, &dsa_p, NULL, NULL); - return BN_num_bits(dsa_p); -} - -static int -ssh_dss_alloc(struct sshkey *k) -{ - if ((k->dsa = DSA_new()) == NULL) - return SSH_ERR_ALLOC_FAIL; - return 0; -} - -static void -ssh_dss_cleanup(struct sshkey *k) -{ - DSA_free(k->dsa); - k->dsa = NULL; -} - -static int -ssh_dss_equal(const struct sshkey *a, const struct sshkey *b) -{ - const BIGNUM *dsa_p_a, *dsa_q_a, *dsa_g_a, *dsa_pub_key_a; - const BIGNUM *dsa_p_b, *dsa_q_b, *dsa_g_b, *dsa_pub_key_b; - - if (a->dsa == NULL || b->dsa == NULL) - return 0; - DSA_get0_pqg(a->dsa, &dsa_p_a, &dsa_q_a, &dsa_g_a); - DSA_get0_pqg(b->dsa, &dsa_p_b, &dsa_q_b, &dsa_g_b); - DSA_get0_key(a->dsa, &dsa_pub_key_a, NULL); - DSA_get0_key(b->dsa, &dsa_pub_key_b, NULL); - if (dsa_p_a == NULL || dsa_p_b == NULL || - dsa_q_a == NULL || dsa_q_b == NULL || - dsa_g_a == NULL || dsa_g_b == NULL || - dsa_pub_key_a == NULL || dsa_pub_key_b == NULL) - return 0; - if (BN_cmp(dsa_p_a, dsa_p_b) != 0) - return 0; - if (BN_cmp(dsa_q_a, dsa_q_b) != 0) - return 0; - if (BN_cmp(dsa_g_a, dsa_g_b) != 0) - return 0; - if (BN_cmp(dsa_pub_key_a, dsa_pub_key_b) != 0) - return 0; - return 1; -} - -static int -ssh_dss_serialize_public(const struct sshkey *key, struct sshbuf *b, - enum sshkey_serialize_rep opts) -{ - int r; - const BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key; - - if (key->dsa == NULL) - return SSH_ERR_INVALID_ARGUMENT; - DSA_get0_pqg(key->dsa, &dsa_p, &dsa_q, &dsa_g); - DSA_get0_key(key->dsa, &dsa_pub_key, NULL); - if (dsa_p == NULL || dsa_q == NULL || - dsa_g == NULL || dsa_pub_key == NULL) - return SSH_ERR_INTERNAL_ERROR; - if ((r = sshbuf_put_bignum2(b, dsa_p)) != 0 || - (r = sshbuf_put_bignum2(b, dsa_q)) != 0 || - (r = sshbuf_put_bignum2(b, dsa_g)) != 0 || - (r = sshbuf_put_bignum2(b, dsa_pub_key)) != 0) - return r; - - return 0; -} - -static int -ssh_dss_serialize_private(const struct sshkey *key, struct sshbuf *b, - enum sshkey_serialize_rep opts) -{ - int r; - const BIGNUM *dsa_priv_key; - - DSA_get0_key(key->dsa, NULL, &dsa_priv_key); - if (!sshkey_is_cert(key)) { - if ((r = ssh_dss_serialize_public(key, b, opts)) != 0) - return r; - } - if ((r = sshbuf_put_bignum2(b, dsa_priv_key)) != 0) - return r; - - return 0; -} - -static int -ssh_dss_generate(struct sshkey *k, int bits) -{ - DSA *private; - - if (bits != 1024) - return SSH_ERR_KEY_LENGTH; - if ((private = DSA_new()) == NULL) - return SSH_ERR_ALLOC_FAIL; - if (!DSA_generate_parameters_ex(private, bits, NULL, 0, NULL, - NULL, NULL) || !DSA_generate_key(private)) { - DSA_free(private); - return SSH_ERR_LIBCRYPTO_ERROR; - } - k->dsa = private; - return 0; -} - -static int -ssh_dss_copy_public(const struct sshkey *from, struct sshkey *to) -{ - const BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key; - BIGNUM *dsa_p_dup = NULL, *dsa_q_dup = NULL, *dsa_g_dup = NULL; - BIGNUM *dsa_pub_key_dup = NULL; - int r = SSH_ERR_INTERNAL_ERROR; - - DSA_get0_pqg(from->dsa, &dsa_p, &dsa_q, &dsa_g); - DSA_get0_key(from->dsa, &dsa_pub_key, NULL); - if ((dsa_p_dup = BN_dup(dsa_p)) == NULL || - (dsa_q_dup = BN_dup(dsa_q)) == NULL || - (dsa_g_dup = BN_dup(dsa_g)) == NULL || - (dsa_pub_key_dup = BN_dup(dsa_pub_key)) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto out; - } - if (!DSA_set0_pqg(to->dsa, dsa_p_dup, dsa_q_dup, dsa_g_dup)) { - r = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } - dsa_p_dup = dsa_q_dup = dsa_g_dup = NULL; /* transferred */ - if (!DSA_set0_key(to->dsa, dsa_pub_key_dup, NULL)) { - r = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } - dsa_pub_key_dup = NULL; /* transferred */ - /* success */ - r = 0; - out: - BN_clear_free(dsa_p_dup); - BN_clear_free(dsa_q_dup); - BN_clear_free(dsa_g_dup); - BN_clear_free(dsa_pub_key_dup); - return r; -} - -static int -ssh_dss_deserialize_public(const char *ktype, struct sshbuf *b, - struct sshkey *key) -{ - int ret = SSH_ERR_INTERNAL_ERROR; - BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL, *dsa_pub_key = NULL; - - if (sshbuf_get_bignum2(b, &dsa_p) != 0 || - sshbuf_get_bignum2(b, &dsa_q) != 0 || - sshbuf_get_bignum2(b, &dsa_g) != 0 || - sshbuf_get_bignum2(b, &dsa_pub_key) != 0) { - ret = SSH_ERR_INVALID_FORMAT; - goto out; - } - if (!DSA_set0_pqg(key->dsa, dsa_p, dsa_q, dsa_g)) { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } - dsa_p = dsa_q = dsa_g = NULL; /* transferred */ - if (!DSA_set0_key(key->dsa, dsa_pub_key, NULL)) { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } - dsa_pub_key = NULL; /* transferred */ -#ifdef DEBUG_PK - DSA_print_fp(stderr, key->dsa, 8); -#endif - /* success */ - ret = 0; - out: - BN_clear_free(dsa_p); - BN_clear_free(dsa_q); - BN_clear_free(dsa_g); - BN_clear_free(dsa_pub_key); - return ret; -} - -static int -ssh_dss_deserialize_private(const char *ktype, struct sshbuf *b, - struct sshkey *key) -{ - int r; - BIGNUM *dsa_priv_key = NULL; - - if (!sshkey_is_cert(key)) { - if ((r = ssh_dss_deserialize_public(ktype, b, key)) != 0) - return r; - } - - if ((r = sshbuf_get_bignum2(b, &dsa_priv_key)) != 0) - return r; - if (!DSA_set0_key(key->dsa, NULL, dsa_priv_key)) { - BN_clear_free(dsa_priv_key); - return SSH_ERR_LIBCRYPTO_ERROR; - } - return 0; -} - -static int -ssh_dss_sign(struct sshkey *key, - u_char **sigp, size_t *lenp, - const u_char *data, size_t datalen, - const char *alg, const char *sk_provider, const char *sk_pin, u_int compat) -{ - DSA_SIG *sig = NULL; - const BIGNUM *sig_r, *sig_s; - u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN]; - size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1); - struct sshbuf *b = NULL; - int ret = SSH_ERR_INVALID_ARGUMENT; - - if (lenp != NULL) - *lenp = 0; - if (sigp != NULL) - *sigp = NULL; - - if (key == NULL || key->dsa == NULL || - sshkey_type_plain(key->type) != KEY_DSA) - return SSH_ERR_INVALID_ARGUMENT; - if (dlen == 0) - return SSH_ERR_INTERNAL_ERROR; - - if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen, - digest, sizeof(digest))) != 0) - goto out; - - if ((sig = DSA_do_sign(digest, dlen, key->dsa)) == NULL) { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } - - DSA_SIG_get0(sig, &sig_r, &sig_s); - rlen = BN_num_bytes(sig_r); - slen = BN_num_bytes(sig_s); - if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) { - ret = SSH_ERR_INTERNAL_ERROR; - goto out; - } - explicit_bzero(sigblob, SIGBLOB_LEN); - BN_bn2bin(sig_r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen); - BN_bn2bin(sig_s, sigblob + SIGBLOB_LEN - slen); - - if ((b = sshbuf_new()) == NULL) { - ret = SSH_ERR_ALLOC_FAIL; - goto out; - } - if ((ret = sshbuf_put_cstring(b, "ssh-dss")) != 0 || - (ret = sshbuf_put_string(b, sigblob, SIGBLOB_LEN)) != 0) - goto out; - - len = sshbuf_len(b); - if (sigp != NULL) { - if ((*sigp = malloc(len)) == NULL) { - ret = SSH_ERR_ALLOC_FAIL; - goto out; - } - memcpy(*sigp, sshbuf_ptr(b), len); - } - if (lenp != NULL) - *lenp = len; - ret = 0; - out: - explicit_bzero(digest, sizeof(digest)); - DSA_SIG_free(sig); - sshbuf_free(b); - return ret; -} - -static int -ssh_dss_verify(const struct sshkey *key, - const u_char *sig, size_t siglen, - const u_char *data, size_t dlen, const char *alg, u_int compat, - struct sshkey_sig_details **detailsp) -{ - DSA_SIG *dsig = NULL; - BIGNUM *sig_r = NULL, *sig_s = NULL; - u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob = NULL; - size_t len, hlen = ssh_digest_bytes(SSH_DIGEST_SHA1); - int ret = SSH_ERR_INTERNAL_ERROR; - struct sshbuf *b = NULL; - char *ktype = NULL; - - if (key == NULL || key->dsa == NULL || - sshkey_type_plain(key->type) != KEY_DSA || - sig == NULL || siglen == 0) - return SSH_ERR_INVALID_ARGUMENT; - if (hlen == 0) - return SSH_ERR_INTERNAL_ERROR; - - /* fetch signature */ - if ((b = sshbuf_from(sig, siglen)) == NULL) - return SSH_ERR_ALLOC_FAIL; - if (sshbuf_get_cstring(b, &ktype, NULL) != 0 || - sshbuf_get_string(b, &sigblob, &len) != 0) { - ret = SSH_ERR_INVALID_FORMAT; - goto out; - } - if (strcmp("ssh-dss", ktype) != 0) { - ret = SSH_ERR_KEY_TYPE_MISMATCH; - goto out; - } - if (sshbuf_len(b) != 0) { - ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; - goto out; - } - - if (len != SIGBLOB_LEN) { - ret = SSH_ERR_INVALID_FORMAT; - goto out; - } - - /* parse signature */ - if ((dsig = DSA_SIG_new()) == NULL || - (sig_r = BN_new()) == NULL || - (sig_s = BN_new()) == NULL) { - ret = SSH_ERR_ALLOC_FAIL; - goto out; - } - if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig_r) == NULL) || - (BN_bin2bn(sigblob + INTBLOB_LEN, INTBLOB_LEN, sig_s) == NULL)) { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } - if (!DSA_SIG_set0(dsig, sig_r, sig_s)) { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } - sig_r = sig_s = NULL; /* transferred */ - - /* sha1 the data */ - if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, dlen, - digest, sizeof(digest))) != 0) - goto out; - - switch (DSA_do_verify(digest, hlen, dsig, key->dsa)) { - case 1: - ret = 0; - break; - case 0: - ret = SSH_ERR_SIGNATURE_INVALID; - goto out; - default: - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } - - out: - explicit_bzero(digest, sizeof(digest)); - DSA_SIG_free(dsig); - BN_clear_free(sig_r); - BN_clear_free(sig_s); - sshbuf_free(b); - free(ktype); - if (sigblob != NULL) - freezero(sigblob, len); - return ret; -} - -static const struct sshkey_impl_funcs sshkey_dss_funcs = { - /* .size = */ ssh_dss_size, - /* .alloc = */ ssh_dss_alloc, - /* .cleanup = */ ssh_dss_cleanup, - /* .equal = */ ssh_dss_equal, - /* .ssh_serialize_public = */ ssh_dss_serialize_public, - /* .ssh_deserialize_public = */ ssh_dss_deserialize_public, - /* .ssh_serialize_private = */ ssh_dss_serialize_private, - /* .ssh_deserialize_private = */ ssh_dss_deserialize_private, - /* .generate = */ ssh_dss_generate, - /* .copy_public = */ ssh_dss_copy_public, - /* .sign = */ ssh_dss_sign, - /* .verify = */ ssh_dss_verify, -}; - -const struct sshkey_impl sshkey_dss_impl = { - /* .name = */ "ssh-dss", - /* .shortname = */ "DSA", - /* .sigalg = */ NULL, - /* .type = */ KEY_DSA, - /* .nid = */ 0, - /* .cert = */ 0, - /* .sigonly = */ 0, - /* .keybits = */ 0, - /* .funcs = */ &sshkey_dss_funcs, -}; - -const struct sshkey_impl sshkey_dsa_cert_impl = { - /* .name = */ "ssh-dss-cert-v01@openssh.com", - /* .shortname = */ "DSA-CERT", - /* .sigalg = */ NULL, - /* .type = */ KEY_DSA_CERT, - /* .nid = */ 0, - /* .cert = */ 1, - /* .sigonly = */ 0, - /* .keybits = */ 0, - /* .funcs = */ &sshkey_dss_funcs, -}; - -#endif /* WITH_OPENSSL && WITH_DSA */ diff --git a/ssh-ecdsa-sk.c b/ssh-ecdsa-sk.c index 27ddf90..eb5c8bc 100644 --- a/ssh-ecdsa-sk.c +++ b/ssh-ecdsa-sk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-ecdsa-sk.c,v 1.19 2024/08/15 00:51:51 djm Exp $ */ +/* $OpenBSD: ssh-ecdsa-sk.c,v 1.21 2026/02/06 22:59:18 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -210,7 +210,7 @@ webauthn_check_prepare_hash(const u_char *data, size_t datalen, fprintf(stderr, "%s: received origin: %s\n", __func__, origin); fprintf(stderr, "%s: received clientData:\n", __func__); sshbuf_dump(wrapper, stderr); - fprintf(stderr, "%s: expected clientData premable:\n", __func__); + fprintf(stderr, "%s: expected clientData preamble:\n", __func__); sshbuf_dump(m, stderr); #endif /* Check that the supplied clientData has the preamble we expect */ @@ -273,7 +273,9 @@ ssh_ecdsa_sk_verify(const struct sshkey *key, ret = SSH_ERR_INVALID_FORMAT; goto out; } - if (strcmp(ktype, "webauthn-sk-ecdsa-sha2-nistp256@openssh.com") == 0) + if (strcmp(ktype, "webauthn-sk-ecdsa-sha2-nistp256@openssh.com") == 0 || + strcmp(ktype, "webauthn-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com") + == 0) is_webauthn = 1; else if (strcmp(ktype, "sk-ecdsa-sha2-nistp256@openssh.com") != 0) { ret = SSH_ERR_INVALID_FORMAT; @@ -310,7 +312,7 @@ ssh_ecdsa_sk_verify(const struct sshkey *key, } #ifdef DEBUG_SK - fprintf(stderr, "%s: data: (len %zu)\n", __func__, datalen); + fprintf(stderr, "%s: data: (len %zu)\n", __func__, dlen); /* sshbuf_dump_data(data, datalen, stderr); */ fprintf(stderr, "%s: sig_r: %s\n", __func__, (tmp = BN_bn2hex(sig_r))); free(tmp); @@ -489,4 +491,16 @@ const struct sshkey_impl sshkey_ecdsa_sk_webauthn_impl = { /* .funcs = */ &sshkey_ecdsa_sk_funcs, }; +const struct sshkey_impl sshkey_ecdsa_sk_webauthn_cert_impl = { + /* .name = */ "webauthn-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com", + /* .shortname = */ "ECDSA-SK-CERT", + /* .sigalg = */ NULL, + /* .type = */ KEY_ECDSA_SK_CERT, + /* .nid = */ NID_X9_62_prime256v1, + /* .cert = */ 1, + /* .sigonly = */ 1, + /* .keybits = */ 256, + /* .funcs = */ &sshkey_ecdsa_sk_funcs, +}; + #endif /* OPENSSL_HAS_ECC */ diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c index 695ed45..526ae74 100644 --- a/ssh-ecdsa.c +++ b/ssh-ecdsa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-ecdsa.c,v 1.27 2024/08/15 00:51:51 djm Exp $ */ +/* $OpenBSD: ssh-ecdsa.c,v 1.29 2026/02/14 00:18:34 jsg Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -27,6 +27,7 @@ #include "includes.h" #if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) +#include "openbsd-compat/openssl-compat.h" #include @@ -39,12 +40,9 @@ #include "sshbuf.h" #include "ssherr.h" -#include "digest.h" #define SSHKEY_INTERNAL #include "sshkey.h" -#include "openbsd-compat/openssl-compat.h" - int sshkey_ecdsa_fixup_group(EVP_PKEY *k) { @@ -328,8 +326,7 @@ ssh_ecdsa_sign(struct sshkey *key, const BIGNUM *sig_r, *sig_s; int hash_alg; size_t slen = 0; - struct sshbuf *b = NULL, *bb = NULL; - int len = 0, ret = SSH_ERR_INTERNAL_ERROR; + int ret = SSH_ERR_INTERNAL_ERROR; if (lenp != NULL) *lenp = 0; @@ -352,11 +349,37 @@ ssh_ecdsa_sign(struct sshkey *key, ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } + ECDSA_SIG_get0(esig, &sig_r, &sig_s); + + if ((ret = ssh_ecdsa_encode_store_sig(key, sig_r, sig_s, + sigp, lenp)) != 0) + goto out; + /* success */ + ret = 0; + out: + freezero(sigb, slen); + ECDSA_SIG_free(esig); + return ret; +} + +int +ssh_ecdsa_encode_store_sig(const struct sshkey *key, + const BIGNUM *sig_r, const BIGNUM *sig_s, + u_char **sigp, size_t *lenp) +{ + struct sshbuf *b = NULL, *bb = NULL; + int ret; + size_t len; + + if (lenp != NULL) + *lenp = 0; + if (sigp != NULL) + *sigp = NULL; + if ((bb = sshbuf_new()) == NULL || (b = sshbuf_new()) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } - ECDSA_SIG_get0(esig, &sig_r, &sig_s); if ((ret = sshbuf_put_bignum2(bb, sig_r)) != 0 || (ret = sshbuf_put_bignum2(bb, sig_s)) != 0) goto out; @@ -375,10 +398,8 @@ ssh_ecdsa_sign(struct sshkey *key, *lenp = len; ret = 0; out: - freezero(sigb, slen); sshbuf_free(b); sshbuf_free(bb); - ECDSA_SIG_free(esig); return ret; } diff --git a/ssh-ed25519-sk.c b/ssh-ed25519-sk.c index c6bc5e7..2c91eb4 100644 --- a/ssh-ed25519-sk.c +++ b/ssh-ed25519-sk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-ed25519-sk.c,v 1.15 2022/10/28 00:44:44 djm Exp $ */ +/* $OpenBSD: ssh-ed25519-sk.c,v 1.16 2026/02/14 00:18:34 jsg Exp $ */ /* * Copyright (c) 2019 Markus Friedl. All rights reserved. * @@ -21,7 +21,6 @@ #define SSHKEY_INTERNAL #include -#include #include "crypto_api.h" @@ -32,7 +31,6 @@ #include "sshbuf.h" #include "sshkey.h" #include "ssherr.h" -#include "ssh.h" #include "digest.h" /* Reuse some ED25519 internals */ diff --git a/ssh-ed25519.c b/ssh-ed25519.c index 22d8db0..2369c3a 100644 --- a/ssh-ed25519.c +++ b/ssh-ed25519.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-ed25519.c,v 1.19 2022/10/28 00:44:44 djm Exp $ */ +/* $OpenBSD: ssh-ed25519.c,v 1.22 2026/02/14 00:18:34 jsg Exp $ */ /* * Copyright (c) 2013 Markus Friedl * @@ -30,7 +30,6 @@ #define SSHKEY_INTERNAL #include "sshkey.h" #include "ssherr.h" -#include "ssh.h" static void ssh_ed25519_cleanup(struct sshkey *k) @@ -149,10 +148,9 @@ ssh_ed25519_sign(struct sshkey *key, const char *alg, const char *sk_provider, const char *sk_pin, u_int compat) { u_char *sig = NULL; - size_t slen = 0, len; + size_t slen = 0; unsigned long long smlen; int r, ret; - struct sshbuf *b = NULL; if (lenp != NULL) *lenp = 0; @@ -173,13 +171,40 @@ ssh_ed25519_sign(struct sshkey *key, r = SSH_ERR_INVALID_ARGUMENT; /* XXX better error? */ goto out; } + if ((r = ssh_ed25519_encode_store_sig(sig, smlen - datalen, + sigp, lenp)) != 0) + goto out; + + /* success */ + r = 0; + out: + freezero(sig, slen); + return r; +} + +int +ssh_ed25519_encode_store_sig(const u_char *sig, size_t slen, + u_char **sigp, size_t *lenp) +{ + struct sshbuf *b = NULL; + int r = -1; + size_t len; + + if (lenp != NULL) + *lenp = 0; + if (sigp != NULL) + *sigp = NULL; + + if (slen != crypto_sign_ed25519_BYTES) + return SSH_ERR_INVALID_ARGUMENT; + /* encode signature */ if ((b = sshbuf_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = sshbuf_put_cstring(b, "ssh-ed25519")) != 0 || - (r = sshbuf_put_string(b, sig, smlen - datalen)) != 0) + (r = sshbuf_put_string(b, sig, slen)) != 0) goto out; len = sshbuf_len(b); if (sigp != NULL) { @@ -195,9 +220,6 @@ ssh_ed25519_sign(struct sshkey *key, r = 0; out: sshbuf_free(b); - if (sig != NULL) - freezero(sig, slen); - return r; } diff --git a/ssh-keygen.0 b/ssh-keygen.0 index 5affcfa..1c1ca77 100644 --- a/ssh-keygen.0 +++ b/ssh-keygen.0 @@ -329,7 +329,7 @@ DESCRIPTION RSA keys). -U When used in combination with -s or -Y sign, this option - indicates that a CA key resides in a ssh-agent(1). See the + indicates that a CA key resides in an ssh-agent(1). See the CERTIFICATES section for more information. -u Update a KRL. When specified with -k, keys listed via the @@ -528,10 +528,6 @@ MODULI GENERATION lines in the input file that have already been processed if the job is restarted. - memory=mbytes - Specify the amount of memory to use (in megabytes) when - generating candidate moduli for DH-GEX. - start=hex-value Specify start point (in hex) when generating candidate moduli for DH-GEX. @@ -554,12 +550,20 @@ CERTIFICATES certificates authenticate users to servers, whereas host certificates authenticate server hosts to users. To generate a user certificate: - $ ssh-keygen -s /path/to/ca_key -I key_id /path/to/user_key.pub + $ ssh-keygen -s /path/to/ca_key -I id -n user \ + M-BM- M-BM- M-BM- M-BM- M-BM- M-BM- /path/to/user_key.pub The resultant certificate will be placed in /path/to/user_key-cert.pub. - A host certificate requires the -h option: + The argument to -I is a key identifier that will be used in logs and may + be used to revoke keys. The argument to -n is one or more (comma- + separated) principals, typically usernames, that the certificate + represents. A host certificate requires the -h option: + + $ ssh-keygen -s /path/to/ca_key -I id -h -n foo.example.org \ + M-BM- M-BM- M-BM- M-BM- M-BM- M-BM- /path/to/host_key.pub - $ ssh-keygen -s /path/to/ca_key -I key_id -h /path/to/host_key.pub + For host certificates, the principals specified using the -n argument are + hostnames and may contain wildcard characters. The host certificate will be output to /path/to/host_key-cert.pub. @@ -567,24 +571,23 @@ CERTIFICATES providing the token library using -D and identifying the CA key by providing its public half as an argument to -s: - $ ssh-keygen -s ca_key.pub -D libpkcs11.so -I key_id user_key.pub + $ ssh-keygen -s ca_key.pub -D libpkcs11.so -I id -n user \ + M-BM- M-BM- M-BM- M-BM- M-BM- M-BM- user_key.pub - Similarly, it is possible for the CA key to be hosted in a ssh-agent(1). + Similarly, it is possible for the CA key to be hosted in an ssh-agent(1). This is indicated by the -U flag and, again, the CA key must be identified by its public half. - $ ssh-keygen -Us ca_key.pub -I key_id user_key.pub + $ ssh-keygen -Us ca_key.pub -I id -n user user_key.pub In all cases, key_id is a "key identifier" that is logged by the server when the certificate is used for authentication. - Certificates may be limited to be valid for a set of principal - (user/host) names. By default, generated certificates are valid for all - users or hosts. To generate a certificate for a specified set of - principals: + Certificates are limited to be valid for a set of principal (user/host) + names. To generate a certificate for a specified set of principals: - $ ssh-keygen -s ca_key -I key_id -n user1,user2 user_key.pub - $ ssh-keygen -s ca_key -I key_id -h -n host.domain host_key.pub + $ ssh-keygen -s ca_key -I id -n user1,user2 user_key.pub + $ ssh-keygen -s ca_key -I id -h -n host.domain host_key.pub Additional limitations on the validity and use of user certificates may be specified through certificate options. A certificate option may @@ -656,17 +659,16 @@ CERTIFICATES verify-required Require signatures made using this key indicate that the user was - first verified. This option only makes sense for the FIDO - authenticator algorithms ecdsa-sk and ed25519-sk. Currently PIN - authentication is the only supported verification method, but - other methods may be supported in the future. + first verified, e.g. by PIN or on-token biometrics. This option + only makes sense for the FIDO authenticator algorithms ecdsa-sk + and ed25519-sk. At present, no standard options are valid for host keys. Finally, certificates may be defined with a validity lifetime. The -V option allows specification of certificate start and end times. A certificate that is presented at a time outside this range will not be - considered valid. By default, certificates are valid from the UNIX Epoch + considered valid. By default, certificates are valid from the Unix Epoch to the distant future. For certificates to be used for user or host authentication, the CA @@ -783,7 +785,7 @@ KEY REVOCATION LISTS OpenSSH versions prior to 7.9. hash: fingerprint - Revokes a key using a fingerprint hash, as obtained from a + Revokes a key using a fingerprint hash, as obtained from an sshd(8) authentication log message or the ssh-keygen -l flag. Only SHA256 fingerprints are supported here and resultant KRLs are not supported by OpenSSH versions prior to 7.9. @@ -906,4 +908,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 7.6 August 17, 2024 OpenBSD 7.6 +OpenBSD 7.8 December 22, 2025 SSH-KEYGEN(1) diff --git a/ssh-keygen.1 b/ssh-keygen.1 index 06f0555..c5f3f74 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keygen.1,v 1.233 2024/08/17 08:35:04 djm Exp $ +.\" $OpenBSD: ssh-keygen.1,v 1.237 2025/12/22 01:49:03 djm Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -35,7 +35,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: August 17 2024 $ +.Dd $Mdocdate: December 22 2025 $ .Dt SSH-KEYGEN 1 .Os .Sh NAME @@ -600,7 +600,7 @@ When used in combination with .Fl s or .Fl Y Cm sign , -this option indicates that a CA key resides in a +this option indicates that a CA key resides in an .Xr ssh-agent 1 . See the .Sx CERTIFICATES @@ -878,9 +878,6 @@ Write the last line processed to the specified file while performing DH candidate screening. This will be used to skip lines in the input file that have already been processed if the job is restarted. -.It Ic memory Ns = Ns Ar mbytes -Specify the amount of memory to use (in megabytes) when generating -candidate moduli for DH-GEX. .It Ic start Ns = Ns Ar hex-value Specify start point (in hex) when generating candidate moduli for DH-GEX. .It Ic generator Ns = Ns Ar value @@ -905,15 +902,29 @@ User certificates authenticate users to servers, whereas host certificates authenticate server hosts to users. To generate a user certificate: .Pp -.Dl $ ssh-keygen -s /path/to/ca_key -I key_id /path/to/user_key.pub +.Dl $ ssh-keygen -s /path/to/ca_key -I id -n user \e +.Dl \ \ \ \ \ \ /path/to/user_key.pub .Pp The resultant certificate will be placed in .Pa /path/to/user_key-cert.pub . +The argument to +.Fl I +is a key identifier that will be used in logs and may be used to revoke +keys. +The argument to +.Fl n +is one or more (comma-separated) principals, typically usernames, that +the certificate represents. A host certificate requires the .Fl h option: .Pp -.Dl $ ssh-keygen -s /path/to/ca_key -I key_id -h /path/to/host_key.pub +.Dl $ ssh-keygen -s /path/to/ca_key -I id -h -n foo.example.org \e +.Dl \ \ \ \ \ \ /path/to/host_key.pub +.Pp +For host certificates, the principals specified using the +.Fl n +argument are hostnames and may contain wildcard characters. .Pp The host certificate will be output to .Pa /path/to/host_key-cert.pub . @@ -925,28 +936,28 @@ and identifying the CA key by providing its public half as an argument to .Fl s : .Pp -.Dl $ ssh-keygen -s ca_key.pub -D libpkcs11.so -I key_id user_key.pub +.Dl $ ssh-keygen -s ca_key.pub -D libpkcs11.so -I id -n user \e +.Dl \ \ \ \ \ \ user_key.pub .Pp -Similarly, it is possible for the CA key to be hosted in a +Similarly, it is possible for the CA key to be hosted in an .Xr ssh-agent 1 . This is indicated by the .Fl U flag and, again, the CA key must be identified by its public half. .Pp -.Dl $ ssh-keygen -Us ca_key.pub -I key_id user_key.pub +.Dl $ ssh-keygen -Us ca_key.pub -I id -n user user_key.pub .Pp In all cases, .Ar key_id is a "key identifier" that is logged by the server when the certificate is used for authentication. .Pp -Certificates may be limited to be valid for a set of principal (user/host) +Certificates are limited to be valid for a set of principal (user/host) names. -By default, generated certificates are valid for all users or hosts. To generate a certificate for a specified set of principals: .Pp -.Dl $ ssh-keygen -s ca_key -I key_id -n user1,user2 user_key.pub -.Dl "$ ssh-keygen -s ca_key -I key_id -h -n host.domain host_key.pub" +.Dl $ ssh-keygen -s ca_key -I id -n user1,user2 user_key.pub +.Dl $ ssh-keygen -s ca_key -I id -h -n host.domain host_key.pub .Pp Additional limitations on the validity and use of user certificates may be specified through certificate options. @@ -1041,13 +1052,11 @@ format. .Pp .It Ic verify-required Require signatures made using this key indicate that the user was first -verified. +verified, e.g. by PIN or on-token biometrics. This option only makes sense for the FIDO authenticator algorithms .Cm ecdsa-sk and .Cm ed25519-sk . -Currently PIN authentication is the only supported verification method, -but other methods may be supported in the future. .El .Pp At present, no standard options are valid for host keys. @@ -1191,7 +1200,7 @@ Revokes the specified key by including its SHA256 hash in the KRL. KRLs that revoke keys by SHA256 hash are not supported by OpenSSH versions prior to 7.9. .It Cm hash : Ar fingerprint -Revokes a key using a fingerprint hash, as obtained from a +Revokes a key using a fingerprint hash, as obtained from an .Xr sshd 8 authentication log message or the .Nm diff --git a/ssh-keygen.c b/ssh-keygen.c index 8396c40..584d5a8 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.475 2024/09/15 00:47:01 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.490 2026/03/03 09:57:25 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -19,20 +19,17 @@ #include #ifdef WITH_OPENSSL +#include "openbsd-compat/openssl-compat.h" +#include #include #include -#include "openbsd-compat/openssl-compat.h" #endif -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include #include -#ifdef HAVE_PATHS_H -# include -#endif +#include #include #include #include @@ -56,7 +53,6 @@ #include "ssh.h" #include "ssh2.h" #include "ssherr.h" -#include "ssh-pkcs11.h" #include "atomicio.h" #include "krl.h" #include "digest.h" @@ -67,21 +63,21 @@ #include "sk-api.h" /* XXX for SSH_SK_USER_PRESENCE_REQD; remove */ #include "cipher.h" +#ifdef ENABLE_PKCS11 +#include "ssh-pkcs11.h" +#endif + #define DEFAULT_KEY_TYPE_NAME "ed25519" /* - * Default number of bits in the RSA, DSA and ECDSA keys. These value can be + * Default number of bits in the RSA and ECDSA keys. These value can be * overridden on the command line. * - * These values, with the exception of DSA, provide security equivalent to at - * least 128 bits of security according to NIST Special Publication 800-57: - * Recommendation for Key Management Part 1 rev 4 section 5.6.1. - * For DSA it (and FIPS-186-4 section 4.2) specifies that the only size for - * which a 160bit hash is acceptable is 1kbit, and since ssh-dss specifies only - * SHA1 we limit the DSA key size 1k bits. + * These values provide security equivalent to at least 128 bits of security + * according to NIST Special Publication 800-57: Recommendation for Key + * Management Part 1 rev 4 section 5.6.1. */ #define DEFAULT_BITS 3072 -#define DEFAULT_BITS_DSA 1024 #define DEFAULT_BITS_ECDSA 256 static int quiet = 0; @@ -113,8 +109,8 @@ static char *cert_key_id = NULL; static char *cert_principals = NULL; /* Validity period for certificates */ -static u_int64_t cert_valid_from = 0; -static u_int64_t cert_valid_to = ~0ULL; +static uint64_t cert_valid_from = 0; +static uint64_t cert_valid_to = ~0ULL; /* Certificate options */ #define CERTOPT_X_FWD (1) @@ -126,7 +122,7 @@ static u_int64_t cert_valid_to = ~0ULL; #define CERTOPT_REQUIRE_VERIFY (1<<6) #define CERTOPT_DEFAULT (CERTOPT_X_FWD|CERTOPT_AGENT_FWD| \ CERTOPT_PORT_FWD|CERTOPT_PTY|CERTOPT_USER_RC) -static u_int32_t certflags_flags = CERTOPT_DEFAULT; +static uint32_t certflags_flags = CERTOPT_DEFAULT; static char *certflags_command = NULL; static char *certflags_src_addr = NULL; @@ -170,13 +166,13 @@ static char hostname[NI_MAXHOST]; #ifdef WITH_OPENSSL /* moduli.c */ -int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *); -int prime_test(FILE *, FILE *, u_int32_t, u_int32_t, char *, unsigned long, +int gen_candidates(FILE *, uint32_t, BIGNUM *); +int prime_test(FILE *, FILE *, uint32_t, uint32_t, char *, unsigned long, unsigned long); #endif static void -type_bits_valid(int type, const char *name, u_int32_t *bitsp) +type_bits_valid(int type, const char *name, uint32_t *bitsp) { if (type == KEY_UNSPEC) fatal("unknown key type %s", key_type_name); @@ -185,9 +181,6 @@ type_bits_valid(int type, const char *name, u_int32_t *bitsp) int nid; switch(type) { - case KEY_DSA: - *bitsp = DEFAULT_BITS_DSA; - break; case KEY_ECDSA: if (name != NULL && (nid = sshkey_ecdsa_nid_from_name(name)) > 0) @@ -203,10 +196,6 @@ type_bits_valid(int type, const char *name, u_int32_t *bitsp) } #ifdef WITH_OPENSSL switch (type) { - case KEY_DSA: - if (*bitsp != 1024) - fatal("Invalid DSA key length: must be 1024 bits"); - break; case KEY_RSA: if (*bitsp < SSH_RSA_MINIMUM_MODULUS_SIZE) fatal("Invalid RSA key length: minimum is %d bits", @@ -262,12 +251,6 @@ ask_filename(struct passwd *pw, const char *prompt) name = _PATH_SSH_CLIENT_ID_ED25519; else { switch (sshkey_type_from_shortname(key_type_name)) { -#ifdef WITH_DSA - case KEY_DSA_CERT: - case KEY_DSA: - name = _PATH_SSH_CLIENT_ID_DSA; - break; -#endif #ifdef OPENSSL_HAS_ECC case KEY_ECDSA_CERT: case KEY_ECDSA: @@ -290,10 +273,6 @@ ask_filename(struct passwd *pw, const char *prompt) case KEY_ED25519_SK_CERT: name = _PATH_SSH_CLIENT_ID_ED25519_SK; break; - case KEY_XMSS: - case KEY_XMSS_CERT: - name = _PATH_SSH_CLIENT_ID_XMSS; - break; default: fatal("bad key type"); } @@ -370,7 +349,6 @@ do_convert_to_ssh2(struct passwd *pw, struct sshkey *k) fprintf(stdout, "Comment: \"%s\"\n%s", comment, b64); fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END); free(b64); - exit(0); } static void @@ -382,12 +360,6 @@ do_convert_to_pkcs8(struct sshkey *k) EVP_PKEY_get0_RSA(k->pkey))) fatal("PEM_write_RSA_PUBKEY failed"); break; -#ifdef WITH_DSA - case KEY_DSA: - if (!PEM_write_DSA_PUBKEY(stdout, k->dsa)) - fatal("PEM_write_DSA_PUBKEY failed"); - break; -#endif #ifdef OPENSSL_HAS_ECC case KEY_ECDSA: if (!PEM_write_EC_PUBKEY(stdout, @@ -398,7 +370,6 @@ do_convert_to_pkcs8(struct sshkey *k) default: fatal_f("unsupported key type %s", sshkey_type(k)); } - exit(0); } static void @@ -410,12 +381,6 @@ do_convert_to_pem(struct sshkey *k) EVP_PKEY_get0_RSA(k->pkey))) fatal("PEM_write_RSAPublicKey failed"); break; -#ifdef WITH_DSA - case KEY_DSA: - if (!PEM_write_DSA_PUBKEY(stdout, k->dsa)) - fatal("PEM_write_DSA_PUBKEY failed"); - break; -#endif #ifdef OPENSSL_HAS_ECC case KEY_ECDSA: if (!PEM_write_EC_PUBKEY(stdout, @@ -426,7 +391,6 @@ do_convert_to_pem(struct sshkey *k) default: fatal_f("unsupported key type %s", sshkey_type(k)); } - exit(0); } static void @@ -455,7 +419,6 @@ do_convert_to(struct passwd *pw) default: fatal_f("unknown key format %d", convert_format); } - exit(0); } /* @@ -491,10 +454,6 @@ do_convert_private_ssh2(struct sshbuf *b) u_int magic, i1, i2, i3, i4; size_t slen; u_long e; -#ifdef WITH_DSA - BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL; - BIGNUM *dsa_pub_key = NULL, *dsa_priv_key = NULL; -#endif BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL; BIGNUM *rsa_p = NULL, *rsa_q = NULL, *rsa_iqmp = NULL; BIGNUM *rsa_dmp1 = NULL, *rsa_dmq1 = NULL; @@ -526,10 +485,6 @@ do_convert_private_ssh2(struct sshbuf *b) if (strstr(type, "rsa")) { ktype = KEY_RSA; -#ifdef WITH_DSA - } else if (strstr(type, "dsa")) { - ktype = KEY_DSA; -#endif } else { free(type); return NULL; @@ -539,27 +494,6 @@ do_convert_private_ssh2(struct sshbuf *b) free(type); switch (key->type) { -#ifdef WITH_DSA - case KEY_DSA: - if ((dsa_p = BN_new()) == NULL || - (dsa_q = BN_new()) == NULL || - (dsa_g = BN_new()) == NULL || - (dsa_pub_key = BN_new()) == NULL || - (dsa_priv_key = BN_new()) == NULL) - fatal_f("BN_new"); - buffer_get_bignum_bits(b, dsa_p); - buffer_get_bignum_bits(b, dsa_g); - buffer_get_bignum_bits(b, dsa_q); - buffer_get_bignum_bits(b, dsa_pub_key); - buffer_get_bignum_bits(b, dsa_priv_key); - if (!DSA_set0_pqg(key->dsa, dsa_p, dsa_q, dsa_g)) - fatal_f("DSA_set0_pqg failed"); - dsa_p = dsa_q = dsa_g = NULL; /* transferred */ - if (!DSA_set0_key(key->dsa, dsa_pub_key, dsa_priv_key)) - fatal_f("DSA_set0_key failed"); - dsa_pub_key = dsa_priv_key = NULL; /* transferred */ - break; -#endif case KEY_RSA: if ((r = sshbuf_get_u8(b, &e1)) != 0 || (e1 < 30 && (r = sshbuf_get_u8(b, &e2)) != 0) || @@ -596,6 +530,7 @@ do_convert_private_ssh2(struct sshbuf *b) if ((r = ssh_rsa_complete_crt_parameters(rsa_d, rsa_p, rsa_q, rsa_iqmp, &rsa_dmp1, &rsa_dmq1)) != 0) fatal_fr(r, "generate RSA CRT parameters"); + EVP_PKEY_free(key->pkey); if ((key->pkey = EVP_PKEY_new()) == NULL) fatal_f("EVP_PKEY_new failed"); if ((rsa = RSA_new()) == NULL) @@ -734,14 +669,6 @@ do_convert_from_pkcs8(struct sshkey **k, int *private) (*k)->pkey = pubkey; pubkey = NULL; break; -#ifdef WITH_DSA - case EVP_PKEY_DSA: - if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) - fatal("sshkey_new failed"); - (*k)->type = KEY_DSA; - (*k)->dsa = EVP_PKEY_get1_DSA(pubkey); - break; -#endif #ifdef OPENSSL_HAS_ECC case EVP_PKEY_EC: if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) @@ -758,7 +685,6 @@ do_convert_from_pkcs8(struct sshkey **k, int *private) EVP_PKEY_base_id(pubkey)); } EVP_PKEY_free(pubkey); - return; } static void @@ -817,12 +743,6 @@ do_convert_from(struct passwd *pw) fprintf(stdout, "\n"); } else { switch (k->type) { -#ifdef WITH_DSA - case KEY_DSA: - ok = PEM_write_DSAPrivateKey(stdout, k->dsa, NULL, - NULL, 0, NULL, NULL); - break; -#endif #ifdef OPENSSL_HAS_ECC case KEY_ECDSA: ok = PEM_write_ECPrivateKey(stdout, @@ -843,7 +763,6 @@ do_convert_from(struct passwd *pw) if (!ok) fatal("key write failed"); sshkey_free(k); - exit(0); } #endif @@ -1008,7 +927,7 @@ do_fingerprint(struct passwd *pw) while (getline(&line, &linesize, f) != -1) { lnum++; cp = line; - cp[strcspn(cp, "\n")] = '\0'; + cp[strcspn(cp, "\r\n")] = '\0'; /* Trim leading space and comments */ cp = line + strspn(line, " \t"); if (*cp == '#' || *cp == '\0') @@ -1096,13 +1015,10 @@ do_gen_all_hostkeys(struct passwd *pw) #endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ { "ed25519", "ED25519",_PATH_HOST_ED25519_KEY_FILE }, -#ifdef WITH_XMSS - { "xmss", "XMSS",_PATH_HOST_XMSS_KEY_FILE }, -#endif /* WITH_XMSS */ { NULL, NULL, NULL } }; - u_int32_t bits = 0; + uint32_t bits = 0; int first = 0; struct stat st; struct sshkey *private, *public; @@ -1526,13 +1442,14 @@ do_print_resource_record(struct passwd *pw, char *fname, char *hname, { struct sshkey *public; char *comment = NULL; + const char *p; struct stat st; int r, hash = -1; size_t i; for (i = 0; i < nopts; i++) { - if (strncasecmp(opts[i], "hashalg=", 8) == 0) { - if ((hash = ssh_digest_alg_by_name(opts[i] + 8)) == -1) + if ((p = strprefix(opts[i], "hashalg=", 1)) != NULL) { + if ((hash = ssh_digest_alg_by_name(p)) == -1) fatal("Unsupported hash algorithm"); } else { error("Invalid option \"%s\"", opts[i]); @@ -1592,7 +1509,7 @@ do_change_comment(struct passwd *pw, const char *identity_comment) } } - if (private->type != KEY_ED25519 && private->type != KEY_XMSS && + if (private->type != KEY_ED25519 && private_key_format != SSHKEY_PRIVATE_OPENSSH) { error("Comments are only supported for keys stored in " "the new format (-o)."); @@ -1796,7 +1713,7 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent, unsigned long long cert_serial, int cert_serial_autoinc, int argc, char **argv) { - int r, i, found, agent_fd = -1; + int r, i, key_in_agent = 0, agent_fd = -1; u_int n; struct sshkey *ca, *public; char valid[64], *otmp, *tmp, *cp, *out, *comment; @@ -1825,17 +1742,19 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent, fatal_r(r, "Cannot use public key for CA signature"); if ((r = ssh_fetch_identitylist(agent_fd, &agent_ids)) != 0) fatal_r(r, "Retrieve agent key list"); - found = 0; for (j = 0; j < agent_ids->nkeys; j++) { if (sshkey_equal(ca, agent_ids->keys[j])) { - found = 1; + key_in_agent = 1; + /* Replace the CA key with the agent one */ + sshkey_free(ca); + ca = agent_ids->keys[j]; + agent_ids->keys[j] = NULL; break; } } - if (!found) + if (!key_in_agent) fatal("CA key %s not found in agent", tmp); ssh_free_identitylist(agent_ids); - ca->flags |= SSHKEY_FLAG_EXT; } else { /* CA key is assumed to be a private key on the filesystem */ ca = load_identity(tmp, NULL); @@ -1887,7 +1806,7 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent, if ((r = sshkey_to_certified(public)) != 0) fatal_r(r, "Could not upgrade key %s to certificate", tmp); public->cert->type = cert_key_type; - public->cert->serial = (u_int64_t)cert_serial; + public->cert->serial = (uint64_t)cert_serial; public->cert->key_id = xstrdup(cert_key_id); public->cert->nprincipals = n; public->cert->principals = plist; @@ -1900,7 +1819,7 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent, &public->cert->signature_key)) != 0) fatal_r(r, "sshkey_from_private (ca key)"); - if (agent_fd != -1 && (ca->flags & SSHKEY_FLAG_EXT) != 0) { + if (key_in_agent) { if ((r = sshkey_certify_custom(public, ca, key_type_name, sk_provider, NULL, agent_signer, &agent_fd)) != 0) @@ -1943,19 +1862,20 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent, sshkey_free(public); free(out); + free(comment); if (cert_serial_autoinc) cert_serial++; } if (pin != NULL) freezero(pin, strlen(pin)); + sshkey_free(ca); free(ca_fp); #ifdef ENABLE_PKCS11 pkcs11_terminate(); #endif - exit(0); } -static u_int64_t +static uint64_t parse_relative_time(const char *s, time_t now) { int64_t mul, secs; @@ -1966,7 +1886,7 @@ parse_relative_time(const char *s, time_t now) fatal("Invalid relative certificate time %s", s); if (mul == -1 && secs > now) fatal("Certificate time %s cannot be represented", s); - return now + (u_int64_t)(secs * mul); + return now + (uint64_t)(secs * mul); } static void @@ -2027,7 +1947,7 @@ parse_cert_times(char *timespec) if (*to == '-' || *to == '+') cert_valid_to = parse_relative_time(to, now); else if (strcmp(to, "forever") == 0) - cert_valid_to = ~(u_int64_t)0; + cert_valid_to = ~(uint64_t)0; else if (strncmp(to, "0x", 2) == 0) parse_hex_u64(to, &cert_valid_to); else if (parse_absolute_time(to, &cert_valid_to) != 0) @@ -2042,6 +1962,7 @@ static void add_cert_option(char *opt) { char *val, *cp; + const char *p; int iscrit = 0; if (strcasecmp(opt, "clear") == 0) @@ -2074,24 +1995,22 @@ add_cert_option(char *opt) certflags_flags &= ~CERTOPT_REQUIRE_VERIFY; else if (strcasecmp(opt, "verify-required") == 0) certflags_flags |= CERTOPT_REQUIRE_VERIFY; - else if (strncasecmp(opt, "force-command=", 14) == 0) { - val = opt + 14; - if (*val == '\0') + else if ((p = strprefix(opt, "force-command=", 1)) != NULL) { + if (*p == '\0') fatal("Empty force-command option"); if (certflags_command != NULL) fatal("force-command already specified"); - certflags_command = xstrdup(val); - } else if (strncasecmp(opt, "source-address=", 15) == 0) { - val = opt + 15; - if (*val == '\0') + certflags_command = xstrdup(p); + } else if ((p = strprefix(opt, "source-address=", 1)) != NULL) { + if (*p == '\0') fatal("Empty source-address option"); if (certflags_src_addr != NULL) fatal("source-address already specified"); - if (addr_match_cidr_list(NULL, val) != 0) + if (addr_match_cidr_list(NULL, p) != 0) fatal("Invalid source-address list"); - certflags_src_addr = xstrdup(val); - } else if (strncasecmp(opt, "extension:", 10) == 0 || - (iscrit = (strncasecmp(opt, "critical:", 9) == 0))) { + certflags_src_addr = xstrdup(p); + } else if (strprefix(opt, "extension:", 1) != NULL || + (iscrit = (strprefix(opt, "critical:", 1) != NULL))) { val = xstrdup(strchr(opt, ':') + 1); if ((cp = strchr(val, '=')) != NULL) *cp++ = '\0'; @@ -2278,9 +2197,8 @@ hash_to_blob(const char *cp, u_char **blobp, size_t *lenp, struct sshbuf *b; int r; - if (strncmp(cp, "SHA256:", 7) != 0) + if ((cp = strprefix(cp, "SHA256:", 0)) == NULL) fatal("%s:%lu: unsupported hash algorithm", file, lnum); - cp += 7; /* * OpenSSH base64 hashes omit trailing '=' @@ -2402,9 +2320,12 @@ update_krl_from_file(struct passwd *pw, const char *file, int wild_ca, cp += 5; cp = cp + strspn(cp, " \t"); hash_to_blob(cp, &blob, &blen, file, lnum); - r = ssh_krl_revoke_key_sha256(krl, blob, blen); - if (r != 0) + if ((r = ssh_krl_revoke_key_sha256(krl, + blob, blen)) != 0) fatal_fr(r, "revoke key failed"); + free(blob); + blob = NULL; + blen = 0; } else { if (strncasecmp(cp, "key:", 4) == 0) { cp += 4; @@ -2705,6 +2626,7 @@ sig_process_opts(char * const *opts, size_t nopts, char **hashalgp, { size_t i; time_t now; + const char *p; if (verify_timep != NULL) *verify_timep = 0; @@ -2714,12 +2636,12 @@ sig_process_opts(char * const *opts, size_t nopts, char **hashalgp, *hashalgp = NULL; for (i = 0; i < nopts; i++) { if (hashalgp != NULL && - strncasecmp(opts[i], "hashalg=", 8) == 0) { - *hashalgp = xstrdup(opts[i] + 8); + (p = strprefix(opts[i], "hashalg=", 1)) != NULL) { + *hashalgp = xstrdup(p); } else if (verify_timep && - strncasecmp(opts[i], "verify-time=", 12) == 0) { - if (parse_absolute_time(opts[i] + 12, - verify_timep) != 0 || *verify_timep == 0) { + (p = strprefix(opts[i], "verify-time=", 1)) != NULL) { + if (parse_absolute_time(p, verify_timep) != 0 || + *verify_timep == 0) { error("Invalid \"verify-time\" option"); return SSH_ERR_INVALID_ARGUMENT; } @@ -2995,32 +2917,22 @@ do_moduli_gen(const char *out_file, char **opts, size_t nopts) { #ifdef WITH_OPENSSL /* Moduli generation/screening */ - u_int32_t memory = 0; BIGNUM *start = NULL; int moduli_bits = 0; FILE *out; size_t i; - const char *errstr; + const char *errstr, *p; /* Parse options */ for (i = 0; i < nopts; i++) { - if (strncmp(opts[i], "memory=", 7) == 0) { - memory = (u_int32_t)strtonum(opts[i]+7, 1, - UINT_MAX, &errstr); - if (errstr) { - fatal("Memory limit is %s: %s", - errstr, opts[i]+7); - } - } else if (strncmp(opts[i], "start=", 6) == 0) { + if ((p = strprefix(opts[i], "start=", 0)) != NULL) { /* XXX - also compare length against bits */ - if (BN_hex2bn(&start, opts[i]+6) == 0) + if (BN_hex2bn(&start, p) == 0) fatal("Invalid start point."); - } else if (strncmp(opts[i], "bits=", 5) == 0) { - moduli_bits = (int)strtonum(opts[i]+5, 1, - INT_MAX, &errstr); + } else if ((p = strprefix(opts[i], "bits=", 0)) != NULL) { + moduli_bits = (int)strtonum(p, 1, INT_MAX, &errstr); if (errstr) { - fatal("Invalid number: %s (%s)", - opts[i]+12, errstr); + fatal("Invalid number: %s (%s)", p, errstr); } } else { fatal("Option \"%s\" is unsupported for moduli " @@ -3028,7 +2940,9 @@ do_moduli_gen(const char *out_file, char **opts, size_t nopts) } } - if ((out = fopen(out_file, "w")) == NULL) { + if (strcmp(out_file, "-") == 0) + out = stdout; + else if ((out = fopen(out_file, "w")) == NULL) { fatal("Couldn't open modulus candidate file \"%s\": %s", out_file, strerror(errno)); } @@ -3036,7 +2950,7 @@ do_moduli_gen(const char *out_file, char **opts, size_t nopts) if (moduli_bits == 0) moduli_bits = DEFAULT_BITS; - if (gen_candidates(out, memory, moduli_bits, start) != 0) + if (gen_candidates(out, moduli_bits, start) != 0) fatal("modulus candidate generation failed"); #else /* WITH_OPENSSL */ fatal("Moduli generation is not supported"); @@ -3049,35 +2963,32 @@ do_moduli_screen(const char *out_file, char **opts, size_t nopts) #ifdef WITH_OPENSSL /* Moduli generation/screening */ char *checkpoint = NULL; - u_int32_t generator_wanted = 0; + uint32_t generator_wanted = 0; unsigned long start_lineno = 0, lines_to_process = 0; int prime_tests = 0; FILE *out, *in = stdin; size_t i; - const char *errstr; + const char *errstr, *p; /* Parse options */ for (i = 0; i < nopts; i++) { - if (strncmp(opts[i], "lines=", 6) == 0) { - lines_to_process = strtoul(opts[i]+6, NULL, 10); - } else if (strncmp(opts[i], "start-line=", 11) == 0) { - start_lineno = strtoul(opts[i]+11, NULL, 10); - } else if (strncmp(opts[i], "checkpoint=", 11) == 0) { + if ((p = strprefix(opts[i], "lines=", 0)) != NULL) { + lines_to_process = strtoul(p, NULL, 10); + } else if ((p = strprefix(opts[i], "start-line=", 0)) != NULL) { + start_lineno = strtoul(p, NULL, 10); + } else if ((p = strprefix(opts[i], "checkpoint=", 0)) != NULL) { free(checkpoint); - checkpoint = xstrdup(opts[i]+11); - } else if (strncmp(opts[i], "generator=", 10) == 0) { - generator_wanted = (u_int32_t)strtonum( - opts[i]+10, 1, UINT_MAX, &errstr); + checkpoint = xstrdup(p); + } else if ((p = strprefix(opts[i], "generator=", 0)) != NULL) { + generator_wanted = (uint32_t)strtonum(p, 1, UINT_MAX, + &errstr); if (errstr != NULL) { - fatal("Generator invalid: %s (%s)", - opts[i]+10, errstr); + fatal("Generator invalid: %s (%s)", p, errstr); } - } else if (strncmp(opts[i], "prime-tests=", 12) == 0) { - prime_tests = (int)strtonum(opts[i]+12, 1, - INT_MAX, &errstr); + } else if ((p = strprefix(opts[i], "prime-tests=", 0)) != NULL) { + prime_tests = (int)strtonum(p, 1, INT_MAX, &errstr); if (errstr) { - fatal("Invalid number: %s (%s)", - opts[i]+12, errstr); + fatal("Invalid number: %s (%s)", p, errstr); } } else { fatal("Option \"%s\" is unsupported for moduli " @@ -3093,7 +3004,9 @@ do_moduli_screen(const char *out_file, char **opts, size_t nopts) } } - if ((out = fopen(out_file, "a")) == NULL) { + if (strcmp(out_file, "-") == 0) + out = stdout; + else if ((out = fopen(out_file, "a")) == NULL) { fatal("Couldn't open moduli file \"%s\": %s", out_file, strerror(errno)); } @@ -3158,13 +3071,14 @@ static char * sk_suffix(const char *application, const uint8_t *user, size_t userlen) { char *ret, *cp; + const char *p; size_t slen, i; /* Trim off URL-like preamble */ - if (strncmp(application, "ssh://", 6) == 0) - ret = xstrdup(application + 6); - else if (strncmp(application, "ssh:", 4) == 0) - ret = xstrdup(application + 4); + if ((p = strprefix(application, "ssh://", 0)) != NULL) + ret = xstrdup(p); + else if ((p = strprefix(application, "ssh:", 0)) != NULL) + ret = xstrdup(p); else ret = xstrdup(application); @@ -3325,7 +3239,7 @@ usage(void) fprintf(stderr, "usage: ssh-keygen [-q] [-a rounds] [-b bits] [-C comment] [-f output_keyfile]\n" " [-m format] [-N new_passphrase] [-O option]\n" - " [-t dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa]\n" + " [-t ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa]\n" " [-w provider] [-Z cipher]\n" " ssh-keygen -p [-a rounds] [-f keyfile] [-m format] [-N new_passphrase]\n" " [-P old_passphrase] [-Z cipher]\n" @@ -3376,9 +3290,9 @@ main(int argc, char **argv) { char comment[1024], *passphrase = NULL; char *rr_hostname = NULL, *ep, *fp, *ra; - struct sshkey *private, *public; + struct sshkey *private = NULL, *public = NULL; struct passwd *pw; - int r, opt, type; + int ret = 0, r, opt, type; int change_passphrase = 0, change_comment = 0, show_cert = 0; int find_host = 0, delete_host = 0, hash_hosts = 0; int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0; @@ -3391,9 +3305,9 @@ main(int argc, char **argv) char *sk_attestation_path = NULL; struct sshbuf *challenge = NULL, *attest = NULL; size_t i, nopts = 0; - u_int32_t bits = 0; + uint32_t bits = 0; uint8_t sk_flags = SSH_SK_USER_PRESENCE_REQD; - const char *errstr; + const char *errstr, *p; int log_level = SYSLOG_LEVEL_INFO; char *sign_op = NULL; @@ -3430,7 +3344,7 @@ main(int argc, char **argv) gen_all_hostkeys = 1; break; case 'b': - bits = (u_int32_t)strtonum(optarg, 1, UINT32_MAX, + bits = (uint32_t)strtonum(optarg, 1, UINT32_MAX, &errstr); if (errstr) fatal("Bits has bad value %s (%s)", @@ -3628,7 +3542,7 @@ main(int argc, char **argv) argc -= optind; if (sign_op != NULL) { - if (strncmp(sign_op, "find-principals", 15) == 0) { + if (strprefix(sign_op, "find-principals", 0) != NULL) { if (ca_key_path == NULL) { error("Too few arguments for find-principals:" "missing signature file"); @@ -3639,9 +3553,10 @@ main(int argc, char **argv) "missing allowed keys file"); exit(1); } - return sig_find_principals(ca_key_path, identity_file, + ret = sig_find_principals(ca_key_path, identity_file, opts, nopts); - } else if (strncmp(sign_op, "match-principals", 16) == 0) { + goto done; + } else if (strprefix(sign_op, "match-principals", 0) != NULL) { if (!have_identity) { error("Too few arguments for match-principals:" "missing allowed keys file"); @@ -3652,9 +3567,10 @@ main(int argc, char **argv) "missing principal ID"); exit(1); } - return sig_match_principals(identity_file, cert_key_id, + ret = sig_match_principals(identity_file, cert_key_id, opts, nopts); - } else if (strncmp(sign_op, "sign", 4) == 0) { + goto done; + } else if (strprefix(sign_op, "sign", 0) != NULL) { /* NB. cert_principals is actually namespace, via -n */ if (cert_principals == NULL || *cert_principals == '\0') { @@ -3667,9 +3583,10 @@ main(int argc, char **argv) "missing key"); exit(1); } - return sig_sign(identity_file, cert_principals, + ret = sig_sign(identity_file, cert_principals, prefer_agent, argc, argv, opts, nopts); - } else if (strncmp(sign_op, "check-novalidate", 16) == 0) { + goto done; + } else if (strprefix(sign_op, "check-novalidate", 0) != NULL) { /* NB. cert_principals is actually namespace, via -n */ if (cert_principals == NULL || *cert_principals == '\0') { @@ -3682,9 +3599,10 @@ main(int argc, char **argv) "missing signature file"); exit(1); } - return sig_verify(ca_key_path, cert_principals, + ret = sig_verify(ca_key_path, cert_principals, NULL, NULL, NULL, opts, nopts); - } else if (strncmp(sign_op, "verify", 6) == 0) { + goto done; + } else if (strprefix(sign_op, "verify", 0) != NULL) { /* NB. cert_principals is actually namespace, via -n */ if (cert_principals == NULL || *cert_principals == '\0') { @@ -3707,9 +3625,10 @@ main(int argc, char **argv) "missing principal identity"); exit(1); } - return sig_verify(ca_key_path, cert_principals, + ret = sig_verify(ca_key_path, cert_principals, cert_key_id, identity_file, rr_hostname, opts, nopts); + goto done; } error("Unsupported operation for -Y: \"%s\"", sign_op); usage(); @@ -3737,19 +3656,29 @@ main(int argc, char **argv) if (gen_krl) { do_gen_krl(pw, update_krl, ca_key_path, cert_serial, identity_comment, argc, argv); - return (0); + goto done; } if (check_krl) { do_check_krl(pw, print_fingerprint, argc, argv); - return (0); + goto done; } if (ca_key_path != NULL) { if (cert_key_id == NULL) fatal("Must specify key id (-I) when certifying"); + if (cert_principals == NULL) { + /* + * Ideally this would be a fatal(), but we need to + * be able to generate such certificates for testing + * even though they will be rejected. + */ + error("Warning: certificate will contain no " + "principals (-n)"); + } for (i = 0; i < nopts; i++) add_cert_option(opts[i]); do_ca_sign(pw, ca_key_path, prefer_agent, cert_serial, cert_serial_autoinc, argc, argv); + goto done; } if (show_cert) do_show_cert(pw); @@ -3761,14 +3690,15 @@ main(int argc, char **argv) do_download(pw); if (download_sk) { for (i = 0; i < nopts; i++) { - if (strncasecmp(opts[i], "device=", 7) == 0) { - sk_device = xstrdup(opts[i] + 7); + if ((p = strprefix(opts[i], "device=", 1)) != NULL) { + sk_device = xstrdup(p); } else { fatal("Option \"%s\" is unsupported for " "FIDO authenticator download", opts[i]); } } - return do_download_sk(sk_provider, sk_device); + ret = do_download_sk(sk_provider, sk_device); + goto done; } if (print_fingerprint || print_bubblebabble) do_fingerprint(pw); @@ -3777,10 +3707,14 @@ main(int argc, char **argv) if (change_comment) do_change_comment(pw, identity_comment); #ifdef WITH_OPENSSL - if (convert_to) + if (convert_to) { do_convert_to(pw); - if (convert_from) + goto done; + } + if (convert_from) { do_convert_from(pw); + goto done; + } #else /* WITH_OPENSSL */ if (convert_to || convert_from) fatal("key conversion disabled at compile time"); @@ -3801,20 +3735,12 @@ main(int argc, char **argv) n += do_print_resource_record(pw, _PATH_HOST_RSA_KEY_FILE, rr_hostname, print_generic, opts, nopts); -#ifdef WITH_DSA - n += do_print_resource_record(pw, - _PATH_HOST_DSA_KEY_FILE, rr_hostname, - print_generic, opts, nopts); -#endif n += do_print_resource_record(pw, _PATH_HOST_ECDSA_KEY_FILE, rr_hostname, print_generic, opts, nopts); n += do_print_resource_record(pw, _PATH_HOST_ED25519_KEY_FILE, rr_hostname, print_generic, opts, nopts); - n += do_print_resource_record(pw, - _PATH_HOST_XMSS_KEY_FILE, rr_hostname, - print_generic, opts, nopts); if (n == 0) fatal("no keys found."); exit(0); @@ -3829,16 +3755,16 @@ main(int argc, char **argv) } if (do_gen_candidates) { do_moduli_gen(argv[0], opts, nopts); - return 0; + goto done; } if (do_screen_candidates) { do_moduli_screen(argv[0], opts, nopts); - return 0; + goto done; } if (gen_all_hostkeys) { do_gen_all_hostkeys(pw); - return (0); + goto done; } if (key_type_name == NULL) @@ -3860,16 +3786,18 @@ main(int argc, char **argv) sk_flags |= SSH_SK_USER_VERIFICATION_REQD; } else if (strcasecmp(opts[i], "resident") == 0) { sk_flags |= SSH_SK_RESIDENT_KEY; - } else if (strncasecmp(opts[i], "device=", 7) == 0) { - sk_device = xstrdup(opts[i] + 7); - } else if (strncasecmp(opts[i], "user=", 5) == 0) { - sk_user = xstrdup(opts[i] + 5); - } else if (strncasecmp(opts[i], "challenge=", 10) == 0) { - if ((r = sshbuf_load_file(opts[i] + 10, + } else if ((p = strprefix(opts[i], "device=", 1)) + != NULL ) { + sk_device = xstrdup(p); + } else if ((p = strprefix(opts[i], "user=", 1)) + != NULL) { + sk_user = xstrdup(p); + } else if ((p = strprefix(opts[i], "challenge=", 1)) + != NULL) { + if ((r = sshbuf_load_file(p, &challenge)) != 0) { fatal_r(r, "Unable to load FIDO " - "enrollment challenge \"%s\"", - opts[i] + 10); + "enrollment challenge \"%s\"", p); } } else if (strncasecmp(opts[i], "write-attestation=", 18) == 0) { @@ -3993,8 +3921,9 @@ main(int argc, char **argv) if (sk_attestation_path != NULL) save_attestation(attest, sk_attestation_path); + done: sshbuf_free(attest); sshkey_free(public); - - exit(0); + pwfree(pw); + exit(ret); } diff --git a/ssh-keyscan.0 b/ssh-keyscan.0 index 382d160..beb5c32 100644 --- a/ssh-keyscan.0 +++ b/ssh-keyscan.0 @@ -34,7 +34,7 @@ DESCRIPTION -c Request certificates from target hosts instead of plain keys. -D Print keys found as SSHFP DNS records. The default is to print - keys in a format usable as a ssh(1) known_hosts file. + keys in a format usable as an ssh(1) known_hosts file. -f file Read hosts or M-bM-^@M-^\addrlist namelistM-bM-^@M-^] pairs from file, one per line. @@ -120,4 +120,4 @@ AUTHORS Davison added support for protocol version 2. -OpenBSD 7.6 June 17, 2024 OpenBSD 7.6 +OpenBSD 7.8 October 4, 2025 SSH-KEYSCAN(1) diff --git a/ssh-keyscan.1 b/ssh-keyscan.1 index 79cef30..e179573 100644 --- a/ssh-keyscan.1 +++ b/ssh-keyscan.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keyscan.1,v 1.52 2024/06/17 08:30:29 djm Exp $ +.\" $OpenBSD: ssh-keyscan.1,v 1.53 2025/10/04 21:41:35 naddy Exp $ .\" .\" Copyright 1995, 1996 by David Mazieres . .\" @@ -6,7 +6,7 @@ .\" permitted provided that due credit is given to the author and the .\" OpenBSD project by leaving this copyright notice intact. .\" -.Dd $Mdocdate: June 17 2024 $ +.Dd $Mdocdate: October 4 2025 $ .Dt SSH-KEYSCAN 1 .Os .Sh NAME @@ -64,7 +64,7 @@ to use IPv6 addresses only. Request certificates from target hosts instead of plain keys. .It Fl D Print keys found as SSHFP DNS records. -The default is to print keys in a format usable as a +The default is to print keys in a format usable as an .Xr ssh 1 .Pa known_hosts file. diff --git a/ssh-keyscan.c b/ssh-keyscan.c index f34e056..9bd3e78 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keyscan.c,v 1.161 2024/09/09 02:39:57 djm Exp $ */ +/* $OpenBSD: ssh-keyscan.c,v 1.167 2025/08/29 03:50:38 djm Exp $ */ /* * Copyright 1995, 1996 by David Mazieres . * @@ -10,11 +10,10 @@ #include "includes.h" #include -#include "openbsd-compat/sys-queue.h" +#include +#include +#include #include -#ifdef HAVE_SYS_TIME_H -# include -#endif #include #include @@ -23,15 +22,13 @@ #include #endif +#include #include #include -#include -#ifdef HAVE_POLL_H -#include -#endif #include #include #include +#include #include #include #include @@ -62,15 +59,13 @@ int IPv4or6 = AF_UNSPEC; int ssh_port = SSH_DEFAULT_PORT; -#define KT_DSA (1) -#define KT_RSA (1<<1) -#define KT_ECDSA (1<<2) -#define KT_ED25519 (1<<3) -#define KT_XMSS (1<<4) -#define KT_ECDSA_SK (1<<5) -#define KT_ED25519_SK (1<<6) +#define KT_RSA (1) +#define KT_ECDSA (1<<1) +#define KT_ED25519 (1<<2) +#define KT_ECDSA_SK (1<<4) +#define KT_ED25519_SK (1<<5) -#define KT_MIN KT_DSA +#define KT_MIN KT_RSA #define KT_MAX KT_ED25519_SK int get_cert = 0; @@ -240,10 +235,6 @@ keygrab_ssh2(con *c) int r; switch (c->c_keytype) { - case KT_DSA: - myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ? - "ssh-dss-cert-v01@openssh.com" : "ssh-dss"; - break; case KT_RSA: myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ? "rsa-sha2-512-cert-v01@openssh.com," @@ -257,10 +248,6 @@ keygrab_ssh2(con *c) myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ? "ssh-ed25519-cert-v01@openssh.com" : "ssh-ed25519"; break; - case KT_XMSS: - myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ? - "ssh-xmss-cert-v01@openssh.com" : "ssh-xmss@openssh.com"; - break; case KT_ECDSA: myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ? "ecdsa-sha2-nistp256-cert-v01@openssh.com," @@ -588,7 +575,7 @@ conloop(void) for (i = 0; i < maxfd; i++) { if (read_wait[i].revents & (POLLHUP|POLLERR|POLLNVAL)) confree(i); - else if (read_wait[i].revents & (POLLIN|POLLHUP)) + else if (read_wait[i].revents & (POLLIN)) conread(i); } @@ -650,22 +637,10 @@ do_host(char *host) if (addr_cmp(&addr, &end_addr) == 0) break; addr_increment(&addr); - }; + } } } -void -sshfatal(const char *file, const char *func, int line, int showfunc, - LogLevel level, const char *suffix, const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - sshlogv(file, func, line, showfunc, level, suffix, fmt, args); - va_end(args); - cleanup_exit(255); -} - static void usage(void) { @@ -755,11 +730,6 @@ main(int argc, char **argv) int type = sshkey_type_from_shortname(tname); switch (type) { -#ifdef WITH_DSA - case KEY_DSA: - get_keytypes |= KT_DSA; - break; -#endif case KEY_ECDSA: get_keytypes |= KT_ECDSA; break; @@ -769,9 +739,6 @@ main(int argc, char **argv) case KEY_ED25519: get_keytypes |= KT_ED25519; break; - case KEY_XMSS: - get_keytypes |= KT_XMSS; - break; case KEY_ED25519_SK: get_keytypes |= KT_ED25519_SK; break; @@ -814,6 +781,7 @@ main(int argc, char **argv) for (j = 0; j < maxfd; j++) read_wait[j].fd = -1; + ssh_signal(SIGPIPE, SIG_IGN); for (j = 0; j < fopt_count; j++) { if (argv[j] == NULL) fp = stdin; diff --git a/ssh-keysign.0 b/ssh-keysign.0 index f1e0e09..569f859 100644 --- a/ssh-keysign.0 +++ b/ssh-keysign.0 @@ -47,4 +47,4 @@ HISTORY AUTHORS Markus Friedl -OpenBSD 7.6 June 17, 2024 OpenBSD 7.6 +OpenBSD 7.8 June 17, 2024 SSH-KEYSIGN(8) diff --git a/ssh-keysign.c b/ssh-keysign.c index 968344e..6cfa511 100644 --- a/ssh-keysign.c +++ b/ssh-keysign.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keysign.c,v 1.74 2024/04/30 05:53:03 djm Exp $ */ +/* $OpenBSD: ssh-keysign.c,v 1.80 2026/03/19 02:36:28 djm Exp $ */ /* * Copyright (c) 2002 Markus Friedl. All rights reserved. * @@ -26,9 +26,7 @@ #include "includes.h" #include -#ifdef HAVE_PATHS_H #include -#endif #include #include #include @@ -131,8 +129,10 @@ valid_request(struct passwd *pw, char *host, struct sshkey **ret, char **pkalgp, /* client host name, handle trailing dot */ if ((r = sshbuf_get_cstring(b, &p, &len)) != 0) fatal_fr(r, "parse hostname"); - debug2_f("check expect chost %s got %s", host, p); - if (strlen(host) != len - 1) + debug2_f("check expect chost \"%s\" got \"%s\"", host, p); + if (len == 0) + fail++; + else if (strlen(host) != len - 1) fail++; else if (p[len - 1] != '.') fail++; @@ -185,9 +185,6 @@ main(int argc, char **argv) char *host, *fp, *pkalg; size_t slen, dlen; - if (pledge("stdio rpath getpw dns id", NULL) != 0) - fatal("%s: pledge: %s", __progname, strerror(errno)); - /* Ensure that stdin and stdout are connected */ if ((fd = open(_PATH_DEVNULL, O_RDWR)) < 2) exit(1); @@ -195,17 +192,16 @@ main(int argc, char **argv) if (fd > 2) close(fd); + if (pledge("stdio rpath getpw dns id", NULL) != 0) + fatal("%s: pledge: %s", __progname, strerror(errno)); + for (i = 0; i < NUM_KEYTYPES; i++) key_fd[i] = -1; i = 0; /* XXX This really needs to read sshd_config for the paths */ -#ifdef WITH_DSA - key_fd[i++] = open(_PATH_HOST_DSA_KEY_FILE, O_RDONLY); -#endif key_fd[i++] = open(_PATH_HOST_ECDSA_KEY_FILE, O_RDONLY); key_fd[i++] = open(_PATH_HOST_ED25519_KEY_FILE, O_RDONLY); - key_fd[i++] = open(_PATH_HOST_XMSS_KEY_FILE, O_RDONLY); key_fd[i++] = open(_PATH_HOST_RSA_KEY_FILE, O_RDONLY); if ((pw = getpwuid(getuid())) == NULL) @@ -222,7 +218,7 @@ main(int argc, char **argv) /* verify that ssh-keysign is enabled by the admin */ initialize_options(&options); - (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, "", "", + (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, "", "", "", &options, 0, NULL); (void)fill_default_options(&options); if (options.enable_ssh_keysign != 1) diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c index b8d1700..6d74d72 100644 --- a/ssh-pkcs11-client.c +++ b/ssh-pkcs11-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11-client.c,v 1.20 2024/08/15 00:51:51 djm Exp $ */ +/* $OpenBSD: ssh-pkcs11-client.c,v 1.26 2026/02/09 22:11:39 dtucker Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * Copyright (c) 2014 Pedro Martelletto. All rights reserved. @@ -18,23 +18,17 @@ #include "includes.h" -#ifdef ENABLE_PKCS11 - #include -#ifdef HAVE_SYS_TIME_H -# include -#endif +#include #include #include +#include #include #include #include #include -#include -#include - #include "pathnames.h" #include "xmalloc.h" #include "sshbuf.h" @@ -46,28 +40,18 @@ #include "ssh-pkcs11.h" #include "ssherr.h" -#include "openbsd-compat/openssl-compat.h" - -#if !defined(OPENSSL_HAS_ECC) || !defined(HAVE_EC_KEY_METHOD_NEW) -#define EC_KEY_METHOD void -#define EC_KEY void -#endif - /* borrows code from sftp-server and ssh-agent */ /* * Maintain a list of ssh-pkcs11-helper subprocesses. These may be looked up - * by provider path or their unique EC/RSA METHOD pointers. + * by provider path or their unique keyblobs. */ struct helper { char *path; pid_t pid; int fd; - RSA_METHOD *rsa_meth; - EC_KEY_METHOD *ec_meth; - int (*rsa_finish)(RSA *rsa); - void (*ec_finish)(EC_KEY *key); - size_t nrsa, nec; /* number of active keys of each type */ + size_t nkeyblobs; + struct sshbuf **keyblobs; /* XXX use a tree or something faster */ }; static struct helper **helpers; static size_t nhelpers; @@ -88,58 +72,75 @@ helper_by_provider(const char *path) } static struct helper * -helper_by_rsa(const RSA *rsa) +helper_by_key(const struct sshkey *key) { - size_t i; - const RSA_METHOD *meth; + size_t i, j; + struct sshbuf *keyblob = NULL; + int r; + + if ((keyblob = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + if ((r = sshkey_putb(key, keyblob)) != 0) + fatal_fr(r, "serialise key"); - if ((meth = RSA_get_method(rsa)) == NULL) - return NULL; for (i = 0; i < nhelpers; i++) { - if (helpers[i] != NULL && helpers[i]->rsa_meth == meth) - return helpers[i]; + if (helpers[i] == NULL) + continue; + for (j = 0; j < helpers[i]->nkeyblobs; j++) { + if (sshbuf_equals(keyblob, + helpers[i]->keyblobs[j]) == 0) { + sshbuf_free(keyblob); + return helpers[i]; + } + } } + sshbuf_free(keyblob); return NULL; } -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) -static struct helper * -helper_by_ec(const EC_KEY *ec) +static void +helper_add_key(struct helper *helper, struct sshkey *key) { - size_t i; - const EC_KEY_METHOD *meth; - - if ((meth = EC_KEY_get_method(ec)) == NULL) - return NULL; - for (i = 0; i < nhelpers; i++) { - if (helpers[i] != NULL && helpers[i]->ec_meth == meth) - return helpers[i]; - } - return NULL; + int r; + helper->keyblobs = xrecallocarray(helper->keyblobs, helper->nkeyblobs, + helper->nkeyblobs + 1, sizeof(*helper->keyblobs)); + if ((helper->keyblobs[helper->nkeyblobs] = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + if ((r = sshkey_putb(key, helper->keyblobs[helper->nkeyblobs])) != 0) + fatal_fr(r, "shkey_putb failed"); + helper->nkeyblobs++; + debug3_f("added %s key for provider %s, now has %zu keys", + sshkey_type(key), helper->path, helper->nkeyblobs); } -#endif /* defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) */ static void -helper_free(struct helper *helper) +helper_terminate(struct helper *helper) { size_t i; int found = 0; if (helper == NULL) return; - if (helper->path == NULL || helper->ec_meth == NULL || - helper->rsa_meth == NULL) + if (helper->path == NULL) fatal_f("inconsistent helper"); - debug3_f("free helper for provider %s", helper->path); + + debug3_f("terminating helper for %s; remaining %zu keys", + helper->path, helper->nkeyblobs); + + close(helper->fd); + /* XXX waitpid() */ + helper->fd = -1; + helper->pid = -1; + + /* repack helpers */ for (i = 0; i < nhelpers; i++) { if (helpers[i] == helper) { if (found) fatal_f("helper recorded more than once"); found = 1; - } - else if (found) + } else if (found) helpers[i - 1] = helpers[i]; } if (found) { @@ -147,39 +148,12 @@ helper_free(struct helper *helper) nhelpers - 1, sizeof(*helpers)); nhelpers--; } + for (i = 0; i < helper->nkeyblobs; i++) + sshbuf_free(helper->keyblobs[i]); free(helper->path); -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) - EC_KEY_METHOD_free(helper->ec_meth); -#endif - RSA_meth_free(helper->rsa_meth); free(helper); } -static void -helper_terminate(struct helper *helper) -{ - if (helper == NULL) { - return; - } else if (helper->fd == -1) { - debug3_f("already terminated"); - } else { - debug3_f("terminating helper for %s; " - "remaining %zu RSA %zu ECDSA", - helper->path, helper->nrsa, helper->nec); - close(helper->fd); - /* XXX waitpid() */ - helper->fd = -1; - helper->pid = -1; - } - /* - * Don't delete the helper entry until there are no remaining keys - * that reference it. Otherwise, any signing operation would call - * a free'd METHOD pointer and that would be bad. - */ - if (helper->nrsa == 0 && helper->nec == 0) - helper_free(helper); -} - static void send_msg(int fd, struct sshbuf *m) { @@ -249,200 +223,62 @@ pkcs11_terminate(void) helper_terminate(helpers[i]); } -static int -rsa_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, int padding) +int +pkcs11_sign(struct sshkey *key, + u_char **sigp, size_t *lenp, + const u_char *data, size_t datalen, + const char *alg, const char *sk_provider, + const char *sk_pin, u_int compat) { - struct sshkey *key = NULL; struct sshbuf *msg = NULL; - u_char *blob = NULL, *signature = NULL; - size_t blen, slen = 0; - int r, ret = -1; struct helper *helper; + int status, r; + u_char *signature = NULL; + size_t signature_len = 0; + int ret = SSH_ERR_INTERNAL_ERROR; - if ((helper = helper_by_rsa(rsa)) == NULL || helper->fd == -1) - fatal_f("no helper for PKCS11 key"); - debug3_f("signing with PKCS11 provider %s", helper->path); - if (padding != RSA_PKCS1_PADDING) - goto fail; - if ((key = sshkey_new(KEY_UNSPEC)) == NULL) { - error_f("sshkey_new failed"); - goto fail; - } - if ((key->pkey = EVP_PKEY_new()) == NULL || - EVP_PKEY_set1_RSA(key->pkey, rsa) != 1) { - error_f("pkey setup failed"); - goto fail; - } + if (sigp != NULL) + *sigp = NULL; + if (lenp != NULL) + *lenp = 0; + + if ((helper = helper_by_key(key)) == NULL || helper->fd == -1) + fatal_f("no helper for %s key", sshkey_type(key)); - key->type = KEY_RSA; - if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) { - error_fr(r, "encode key"); - goto fail; - } if ((msg = sshbuf_new()) == NULL) - fatal_f("sshbuf_new failed"); + return SSH_ERR_ALLOC_FAIL; if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 || - (r = sshbuf_put_string(msg, blob, blen)) != 0 || - (r = sshbuf_put_string(msg, from, flen)) != 0 || - (r = sshbuf_put_u32(msg, 0)) != 0) + (r = sshkey_puts_plain(key, msg)) != 0 || + (r = sshbuf_put_string(msg, data, datalen)) != 0 || + (r = sshbuf_put_cstring(msg, alg == NULL ? "" : alg)) != 0 || + (r = sshbuf_put_u32(msg, compat)) != 0) fatal_fr(r, "compose"); send_msg(helper->fd, msg); sshbuf_reset(msg); - if (recv_msg(helper->fd, msg) == SSH2_AGENT_SIGN_RESPONSE) { - if ((r = sshbuf_get_string(msg, &signature, &slen)) != 0) - fatal_fr(r, "parse"); - if (slen <= (size_t)RSA_size(rsa)) { - memcpy(to, signature, slen); - ret = slen; - } - free(signature); - } - fail: - free(blob); - sshkey_free(key); - sshbuf_free(msg); - return (ret); -} - -static int -rsa_finish(RSA *rsa) -{ - struct helper *helper; - - if ((helper = helper_by_rsa(rsa)) == NULL) - fatal_f("no helper for PKCS11 key"); - debug3_f("free PKCS11 RSA key for provider %s", helper->path); - if (helper->rsa_finish != NULL) - helper->rsa_finish(rsa); - if (helper->nrsa == 0) - fatal_f("RSA refcount error"); - helper->nrsa--; - debug3_f("provider %s remaining keys: %zu RSA %zu ECDSA", - helper->path, helper->nrsa, helper->nec); - if (helper->nrsa == 0 && helper->nec == 0) - helper_terminate(helper); - return 1; -} - -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) -static ECDSA_SIG * -ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, - const BIGNUM *rp, EC_KEY *ec) -{ - struct sshkey *key = NULL; - struct sshbuf *msg = NULL; - ECDSA_SIG *ret = NULL; - const u_char *cp; - u_char *blob = NULL, *signature = NULL; - size_t blen, slen = 0; - int r, nid; - struct helper *helper; - - if ((helper = helper_by_ec(ec)) == NULL || helper->fd == -1) - fatal_f("no helper for PKCS11 key"); - debug3_f("signing with PKCS11 provider %s", helper->path); - - if ((key = sshkey_new(KEY_UNSPEC)) == NULL) { - error_f("sshkey_new failed"); - goto fail; - } - if ((key->pkey = EVP_PKEY_new()) == NULL || - EVP_PKEY_set1_EC_KEY(key->pkey, ec) != 1) { - error("pkey setup failed"); - goto fail; - } - if ((nid = sshkey_ecdsa_pkey_to_nid(key->pkey)) < 0) { - error("couldn't get curve nid"); + if ((status = recv_msg(helper->fd, msg)) != SSH2_AGENT_SIGN_RESPONSE) { + /* XXX translate status to something useful */ + debug_fr(r, "recv_msg"); + ret = SSH_ERR_AGENT_FAILURE; goto fail; } - key->ecdsa_nid = nid; - key->type = KEY_ECDSA; - if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) { - error_fr(r, "encode key"); - goto fail; - } - if ((msg = sshbuf_new()) == NULL) - fatal_f("sshbuf_new failed"); - if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 || - (r = sshbuf_put_string(msg, blob, blen)) != 0 || - (r = sshbuf_put_string(msg, dgst, dgst_len)) != 0 || - (r = sshbuf_put_u32(msg, 0)) != 0) - fatal_fr(r, "compose"); - send_msg(helper->fd, msg); - sshbuf_reset(msg); + if ((r = sshbuf_get_string(msg, &signature, &signature_len)) != 0) + fatal_fr(r, "parse"); - if (recv_msg(helper->fd, msg) == SSH2_AGENT_SIGN_RESPONSE) { - if ((r = sshbuf_get_string(msg, &signature, &slen)) != 0) - fatal_fr(r, "parse"); - cp = signature; - ret = d2i_ECDSA_SIG(NULL, &cp, slen); - free(signature); + /* success */ + if (sigp != NULL) { + *sigp = signature; + signature = NULL; } + if (lenp != NULL) + *lenp = signature_len; + ret = 0; fail: - free(blob); - sshkey_free(key); + free(signature); sshbuf_free(msg); - return (ret); -} - -static void -ecdsa_do_finish(EC_KEY *ec) -{ - struct helper *helper; - - if ((helper = helper_by_ec(ec)) == NULL) - fatal_f("no helper for PKCS11 key"); - debug3_f("free PKCS11 ECDSA key for provider %s", helper->path); - if (helper->ec_finish != NULL) - helper->ec_finish(ec); - if (helper->nec == 0) - fatal_f("ECDSA refcount error"); - helper->nec--; - debug3_f("provider %s remaining keys: %zu RSA %zu ECDSA", - helper->path, helper->nrsa, helper->nec); - if (helper->nrsa == 0 && helper->nec == 0) - helper_terminate(helper); -} -#endif /* defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) */ - -/* redirect private key crypto operations to the ssh-pkcs11-helper */ -static void -wrap_key(struct helper *helper, struct sshkey *k) -{ - RSA *rsa = NULL; - EC_KEY *ecdsa = NULL; - - debug3_f("wrap %s for provider %s", sshkey_type(k), helper->path); - if (k->type == KEY_RSA) { - if ((rsa = EVP_PKEY_get1_RSA(k->pkey)) == NULL) - fatal_f("no RSA key"); - if (RSA_set_method(rsa, helper->rsa_meth) != 1) - fatal_f("RSA_set_method failed"); - if (helper->nrsa++ >= INT_MAX) - fatal_f("RSA refcount error"); - if (EVP_PKEY_set1_RSA(k->pkey, rsa) != 1) - fatal_f("EVP_PKEY_set1_RSA failed"); - RSA_free(rsa); -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) - } else if (k->type == KEY_ECDSA) { - if ((ecdsa = EVP_PKEY_get1_EC_KEY(k->pkey)) == NULL) - fatal_f("no ECDSA key"); - if (EC_KEY_set_method(ecdsa, helper->ec_meth) != 1) - fatal_f("EC_KEY_set_method failed"); - if (helper->nec++ >= INT_MAX) - fatal_f("EC refcount error"); - if (EVP_PKEY_set1_EC_KEY(k->pkey, ecdsa) != 1) - fatal_f("EVP_PKEY_set1_EC_KEY failed"); - EC_KEY_free(ecdsa); -#endif - } else - fatal_f("unknown key type"); - k->flags |= SSHKEY_FLAG_EXT; - debug3_f("provider %s remaining keys: %zu RSA %zu ECDSA", - helper->path, helper->nrsa, helper->nec); + return ret; } /* @@ -456,13 +292,13 @@ pkcs11_make_cert(const struct sshkey *priv, struct helper *helper = NULL; struct sshkey *ret; int r; - RSA *rsa_priv = NULL, *rsa_cert = NULL; -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) - EC_KEY *ec_priv = NULL, *ec_cert = NULL; -#endif - debug3_f("private key type %s cert type %s", sshkey_type(priv), - sshkey_type(certpub)); + if ((helper = helper_by_key(priv)) == NULL || helper->fd == -1) + fatal_f("no helper for %s key", sshkey_type(priv)); + + debug3_f("private key type %s cert type %s on provider %s", + sshkey_type(priv), sshkey_type(certpub), helper->path); + *certprivp = NULL; if (!sshkey_is_cert(certpub) || sshkey_is_cert(priv) || !sshkey_equal_public(priv, certpub)) { @@ -471,95 +307,24 @@ pkcs11_make_cert(const struct sshkey *priv, return SSH_ERR_INVALID_ARGUMENT; } *certprivp = NULL; - if (priv->type == KEY_RSA) { - if ((rsa_priv = EVP_PKEY_get1_RSA(priv->pkey)) == NULL) - fatal_f("no RSA pkey"); - if ((helper = helper_by_rsa(rsa_priv)) == NULL || - helper->fd == -1) - fatal_f("no helper for PKCS11 RSA key"); - if ((r = sshkey_from_private(priv, &ret)) != 0) - fatal_fr(r, "copy key"); - if ((rsa_cert = EVP_PKEY_get1_RSA(ret->pkey)) == NULL) - fatal_f("no RSA cert pkey"); - if (RSA_set_method(rsa_cert, helper->rsa_meth) != 1) - fatal_f("RSA_set_method failed"); - if (helper->nrsa++ >= INT_MAX) - fatal_f("RSA refcount error"); - if (EVP_PKEY_set1_RSA(ret->pkey, rsa_cert) != 1) - fatal_f("EVP_PKEY_set1_RSA failed"); - RSA_free(rsa_priv); - RSA_free(rsa_cert); -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) - } else if (priv->type == KEY_ECDSA) { - if ((ec_priv = EVP_PKEY_get1_EC_KEY(priv->pkey)) == NULL) - fatal_f("no EC pkey"); - if ((helper = helper_by_ec(ec_priv)) == NULL || - helper->fd == -1) - fatal_f("no helper for PKCS11 EC key"); - if ((r = sshkey_from_private(priv, &ret)) != 0) - fatal_fr(r, "copy key"); - if ((ec_cert = EVP_PKEY_get1_EC_KEY(ret->pkey)) == NULL) - fatal_f("no EC cert pkey"); - if (EC_KEY_set_method(ec_cert, helper->ec_meth) != 1) - fatal_f("EC_KEY_set_method failed"); - if (helper->nec++ >= INT_MAX) - fatal_f("EC refcount error"); - if (EVP_PKEY_set1_EC_KEY(ret->pkey, ec_cert) != 1) - fatal_f("EVP_PKEY_set1_EC_KEY failed"); - EC_KEY_free(ec_priv); - EC_KEY_free(ec_cert); -#endif - } else - fatal_f("unknown key type %s", sshkey_type(priv)); + if ((r = sshkey_from_private(priv, &ret)) != 0) + fatal_fr(r, "copy key"); ret->flags |= SSHKEY_FLAG_EXT; if ((r = sshkey_to_certified(ret)) != 0 || (r = sshkey_cert_copy(certpub, ret)) != 0) fatal_fr(r, "graft certificate"); - debug3_f("provider %s remaining keys: %zu RSA %zu ECDSA", - helper->path, helper->nrsa, helper->nec); + + helper_add_key(helper, ret); + + debug3_f("provider %s: %zu remaining keys", + helper->path, helper->nkeyblobs); + /* success */ *certprivp = ret; return 0; } -static int -pkcs11_start_helper_methods(struct helper *helper) -{ - RSA_METHOD *rsa_meth = NULL; - EC_KEY_METHOD *ec_meth = NULL; -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) - int (*ec_init)(EC_KEY *key); - int (*ec_copy)(EC_KEY *dest, const EC_KEY *src); - int (*ec_set_group)(EC_KEY *key, const EC_GROUP *grp); - int (*ec_set_private)(EC_KEY *key, const BIGNUM *priv_key); - int (*ec_set_public)(EC_KEY *key, const EC_POINT *pub_key); - int (*ec_sign)(int, const unsigned char *, int, unsigned char *, - unsigned int *, const BIGNUM *, const BIGNUM *, EC_KEY *) = NULL; - - if ((ec_meth = EC_KEY_METHOD_new(EC_KEY_OpenSSL())) == NULL) - return -1; - EC_KEY_METHOD_get_sign(ec_meth, &ec_sign, NULL, NULL); - EC_KEY_METHOD_set_sign(ec_meth, ec_sign, NULL, ecdsa_do_sign); - EC_KEY_METHOD_get_init(ec_meth, &ec_init, &helper->ec_finish, - &ec_copy, &ec_set_group, &ec_set_private, &ec_set_public); - EC_KEY_METHOD_set_init(ec_meth, ec_init, ecdsa_do_finish, - ec_copy, ec_set_group, ec_set_private, ec_set_public); -#endif /* defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) */ - - if ((rsa_meth = RSA_meth_dup(RSA_get_default_method())) == NULL) - fatal_f("RSA_meth_dup failed"); - helper->rsa_finish = RSA_meth_get_finish(rsa_meth); - if (!RSA_meth_set1_name(rsa_meth, "ssh-pkcs11-helper") || - !RSA_meth_set_priv_enc(rsa_meth, rsa_encrypt) || - !RSA_meth_set_finish(rsa_meth, rsa_finish)) - fatal_f("failed to prepare method"); - - helper->ec_meth = ec_meth; - helper->rsa_meth = rsa_meth; - return 0; -} - static struct helper * pkcs11_start_helper(const char *path) { @@ -576,19 +341,10 @@ pkcs11_start_helper(const char *path) return NULL; } helper = xcalloc(1, sizeof(*helper)); - if (pkcs11_start_helper_methods(helper) == -1) { - error_f("pkcs11_start_helper_methods failed"); - goto fail; - } if ((pid = fork()) == -1) { error_f("fork: %s", strerror(errno)); - fail: close(pair[0]); close(pair[1]); - RSA_meth_free(helper->rsa_meth); -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) - EC_KEY_METHOD_free(helper->ec_meth); -#endif free(helper); return NULL; } else if (pid == 0) { @@ -599,6 +355,7 @@ pkcs11_start_helper(const char *path) } close(pair[0]); close(pair[1]); + closefrom(STDERR_FILENO + 1); prog = getenv("SSH_PKCS11_HELPER"); if (prog == NULL || strlen(prog) == 0) prog = _PATH_SSH_PKCS11_HELPER; @@ -628,10 +385,8 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp, { struct sshkey *k; int r, type; - u_char *blob; char *label; - size_t blen; - u_int nkeys, i; + u_int ret = -1, nkeys, i; struct sshbuf *msg; struct helper *helper; @@ -639,6 +394,8 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp, (helper = pkcs11_start_helper(name)) == NULL) return -1; + debug3_f("add %s", helper->path); + if ((msg = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); if ((r = sshbuf_put_u8(msg, SSH_AGENTC_ADD_SMARTCARD_KEY)) != 0 || @@ -649,35 +406,39 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp, sshbuf_reset(msg); type = recv_msg(helper->fd, msg); + debug3_f("response %d", type); if (type == SSH2_AGENT_IDENTITIES_ANSWER) { if ((r = sshbuf_get_u32(msg, &nkeys)) != 0) fatal_fr(r, "parse nkeys"); + debug3_f("helper return %u keys", nkeys); *keysp = xcalloc(nkeys, sizeof(struct sshkey *)); if (labelsp) *labelsp = xcalloc(nkeys, sizeof(char *)); for (i = 0; i < nkeys; i++) { /* XXX clean up properly instead of fatal() */ - if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 || + if ((r = sshkey_froms(msg, &k)) != 0 || (r = sshbuf_get_cstring(msg, &label, NULL)) != 0) fatal_fr(r, "parse key"); - if ((r = sshkey_from_blob(blob, blen, &k)) != 0) - fatal_fr(r, "decode key"); - wrap_key(helper, k); + k->flags |= SSHKEY_FLAG_EXT; + helper_add_key(helper, k); (*keysp)[i] = k; if (labelsp) (*labelsp)[i] = label; else free(label); - free(blob); } + /* success */ + ret = 0; } else if (type == SSH2_AGENT_FAILURE) { if ((r = sshbuf_get_u32(msg, &nkeys)) != 0) - nkeys = -1; - } else { - nkeys = -1; + error_fr(r, "failed to parse failure response"); + } + if (ret != 0) { + debug_f("no keys; terminate helper"); + helper_terminate(helper); } sshbuf_free(msg); - return (nkeys); + return ret == 0 ? (int)nkeys : -1; } int @@ -689,9 +450,44 @@ pkcs11_del_provider(char *name) * ssh-agent deletes keys before calling this, so the helper entry * should be gone before we get here. */ - debug3_f("delete %s", name); + debug3_f("delete %s", name ? name : "(null)"); if ((helper = helper_by_provider(name)) != NULL) helper_terminate(helper); return 0; } -#endif /* ENABLE_PKCS11 */ + +void +pkcs11_key_free(struct sshkey *key) +{ + struct helper *helper; + struct sshbuf *keyblob = NULL; + size_t i; + int r, found = 0; + + debug3_f("free %s key", sshkey_type(key)); + + if ((helper = helper_by_key(key)) == NULL || helper->fd == -1) + fatal_f("no helper for %s key", sshkey_type(key)); + if ((keyblob = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + if ((r = sshkey_putb(key, keyblob)) != 0) + fatal_fr(r, "serialise key"); + + /* repack keys */ + for (i = 0; i < helper->nkeyblobs; i++) { + if (sshbuf_equals(keyblob, helper->keyblobs[i]) == 0) { + if (found) + fatal_f("key recorded more than once"); + found = 1; + } else if (found) + helper->keyblobs[i - 1] = helper->keyblobs[i]; + } + if (found) { + helper->keyblobs = xrecallocarray(helper->keyblobs, + helper->nkeyblobs, helper->nkeyblobs - 1, + sizeof(*helper->keyblobs)); + helper->nkeyblobs--; + } + if (helper->nkeyblobs == 0) + helper_terminate(helper); +} diff --git a/ssh-pkcs11-helper.0 b/ssh-pkcs11-helper.0 index 42a6a20..ccb05e2 100644 --- a/ssh-pkcs11-helper.0 +++ b/ssh-pkcs11-helper.0 @@ -32,4 +32,4 @@ HISTORY AUTHORS Markus Friedl -OpenBSD 7.6 April 29, 2022 OpenBSD 7.6 +OpenBSD 7.8 April 29, 2022 SSH-PKCS11-HELPER(8) diff --git a/ssh-pkcs11-helper.c b/ssh-pkcs11-helper.c index a8154f2..f7b7b2e 100644 --- a/ssh-pkcs11-helper.c +++ b/ssh-pkcs11-helper.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11-helper.c,v 1.27 2024/08/15 00:51:51 djm Exp $ */ +/* $OpenBSD: ssh-pkcs11-helper.c,v 1.31 2026/02/11 17:03:17 dtucker Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * @@ -18,17 +18,11 @@ #include "includes.h" #include -#ifdef HAVE_SYS_TIME_H -# include -#endif - -#include "openbsd-compat/sys-queue.h" +#include #include #include -#ifdef HAVE_POLL_H #include -#endif #include #include #include @@ -44,20 +38,9 @@ #ifdef ENABLE_PKCS11 -#ifdef WITH_OPENSSL -#include -#include -#include - /* borrows code from sftp-server and ssh-agent */ -struct pkcs11_keyinfo { - struct sshkey *key; - char *providername, *label; - TAILQ_ENTRY(pkcs11_keyinfo) next; -}; - -TAILQ_HEAD(, pkcs11_keyinfo) pkcs11_keylist; +static char *providername; /* Provider for this helper */ #define MAX_MSG_LENGTH 10240 /*XXX*/ @@ -65,50 +48,6 @@ TAILQ_HEAD(, pkcs11_keyinfo) pkcs11_keylist; struct sshbuf *iqueue; struct sshbuf *oqueue; -static void -add_key(struct sshkey *k, char *name, char *label) -{ - struct pkcs11_keyinfo *ki; - - ki = xcalloc(1, sizeof(*ki)); - ki->providername = xstrdup(name); - ki->key = k; - ki->label = xstrdup(label); - TAILQ_INSERT_TAIL(&pkcs11_keylist, ki, next); -} - -static void -del_keys_by_name(char *name) -{ - struct pkcs11_keyinfo *ki, *nxt; - - for (ki = TAILQ_FIRST(&pkcs11_keylist); ki; ki = nxt) { - nxt = TAILQ_NEXT(ki, next); - if (!strcmp(ki->providername, name)) { - TAILQ_REMOVE(&pkcs11_keylist, ki, next); - free(ki->providername); - free(ki->label); - sshkey_free(ki->key); - free(ki); - } - } -} - -/* lookup matching 'private' key */ -static struct sshkey * -lookup_key(struct sshkey *k) -{ - struct pkcs11_keyinfo *ki; - - TAILQ_FOREACH(ki, &pkcs11_keylist, next) { - debug("check %s %s %s", sshkey_type(ki->key), - ki->providername, ki->label); - if (sshkey_equal(k, ki->key)) - return (ki->key); - } - return (NULL); -} - static void send_msg(struct sshbuf *m) { @@ -121,34 +60,32 @@ send_msg(struct sshbuf *m) static void process_add(void) { - char *name, *pin; + char *pin; struct sshkey **keys = NULL; int r, i, nkeys; - u_char *blob; - size_t blen; struct sshbuf *msg; char **labels = NULL; + if (providername != NULL) + fatal_f("provider already set"); if ((msg = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); - if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 || + if ((r = sshbuf_get_cstring(iqueue, &providername, NULL)) != 0 || (r = sshbuf_get_cstring(iqueue, &pin, NULL)) != 0) fatal_fr(r, "parse"); - if ((nkeys = pkcs11_add_provider(name, pin, &keys, &labels)) > 0) { + debug3_f("add %s", providername); + if ((nkeys = pkcs11_add_provider(providername, pin, + &keys, &labels)) > 0) { if ((r = sshbuf_put_u8(msg, SSH2_AGENT_IDENTITIES_ANSWER)) != 0 || (r = sshbuf_put_u32(msg, nkeys)) != 0) fatal_fr(r, "compose"); for (i = 0; i < nkeys; i++) { - if ((r = sshkey_to_blob(keys[i], &blob, &blen)) != 0) { - debug_fr(r, "encode key"); - continue; - } - if ((r = sshbuf_put_string(msg, blob, blen)) != 0 || + if ((r = sshkey_puts(keys[i], msg)) != 0 || (r = sshbuf_put_cstring(msg, labels[i])) != 0) fatal_fr(r, "compose key"); - free(blob); - add_key(keys[i], name, labels[i]); + debug3_f("%s: %s \"%s\"", providername, + sshkey_type(keys[i]), labels[i]); free(labels[i]); } } else if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0 || @@ -157,95 +94,39 @@ process_add(void) free(labels); free(keys); /* keys themselves are transferred to pkcs11_keylist */ free(pin); - free(name); send_msg(msg); sshbuf_free(msg); } static void -process_del(void) +process_sign(void) { - char *name, *pin; + const u_char *data; + u_char *signature = NULL; + size_t dlen, slen = 0; + u_int compat; + int r, ok = -1; + struct sshkey *key = NULL; struct sshbuf *msg; - int r; + char *alg = NULL; - if ((msg = sshbuf_new()) == NULL) - fatal_f("sshbuf_new failed"); - if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 || - (r = sshbuf_get_cstring(iqueue, &pin, NULL)) != 0) + if ((r = sshkey_froms(iqueue, &key)) != 0 || + (r = sshbuf_get_string_direct(iqueue, &data, &dlen)) != 0 || + (r = sshbuf_get_cstring(iqueue, &alg, NULL)) != 0 || + (r = sshbuf_get_u32(iqueue, &compat)) != 0) fatal_fr(r, "parse"); - del_keys_by_name(name); - if ((r = sshbuf_put_u8(msg, pkcs11_del_provider(name) == 0 ? - SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE)) != 0) - fatal_fr(r, "compose"); - free(pin); - free(name); - send_msg(msg); - sshbuf_free(msg); -} -static void -process_sign(void) -{ - u_char *blob, *data, *signature = NULL; - size_t blen, dlen; - u_int slen = 0; - int len, r, ok = -1; - struct sshkey *key = NULL, *found; - struct sshbuf *msg; -#ifdef WITH_OPENSSL - RSA *rsa = NULL; -#ifdef OPENSSL_HAS_ECC - EC_KEY *ecdsa = NULL; -#endif /* OPENSSL_HAS_ECC */ -#endif /* WITH_OPENSSL */ - - /* XXX support SHA2 signature flags */ - if ((r = sshbuf_get_string(iqueue, &blob, &blen)) != 0 || - (r = sshbuf_get_string(iqueue, &data, &dlen)) != 0 || - (r = sshbuf_get_u32(iqueue, NULL)) != 0) - fatal_fr(r, "parse"); + if (*alg == '\0') { + free(alg); + alg = NULL; + } - if ((r = sshkey_from_blob(blob, blen, &key)) != 0) - fatal_fr(r, "decode key"); - if ((found = lookup_key(key)) == NULL) + if ((r = pkcs11_sign(key, &signature, &slen, data, dlen, + alg, NULL, NULL, compat)) != 0) { + error_fr(r, "sign %s", sshkey_type(key)); goto reply; - - /* XXX use pkey API properly for signing */ - switch (key->type) { -#ifdef WITH_OPENSSL - case KEY_RSA: - if ((rsa = EVP_PKEY_get1_RSA(found->pkey)) == NULL) - fatal_f("no RSA in pkey"); - if ((len = RSA_size(rsa)) < 0) - fatal_f("bad RSA length"); - signature = xmalloc(len); - if ((len = RSA_private_encrypt(dlen, data, signature, - rsa, RSA_PKCS1_PADDING)) < 0) { - error_f("RSA_private_encrypt failed"); - goto reply; - } - slen = (u_int)len; - break; -#ifdef OPENSSL_HAS_ECC - case KEY_ECDSA: - if ((ecdsa = EVP_PKEY_get1_EC_KEY(found->pkey)) == NULL) - fatal_f("no ECDSA in pkey"); - if ((len = ECDSA_size(ecdsa)) < 0) - fatal_f("bad ECDSA length"); - slen = (u_int)len; - signature = xmalloc(slen); - /* "The parameter type is ignored." */ - if (!ECDSA_sign(-1, data, dlen, signature, &slen, ecdsa)) { - error_f("ECDSA_sign failed"); - goto reply; - } - break; -#endif /* OPENSSL_HAS_ECC */ -#endif /* WITH_OPENSSL */ - default: - fatal_f("unsupported key type %d", key->type); } + /* success */ ok = 0; reply: @@ -260,12 +141,7 @@ process_sign(void) fatal_fr(r, "compose failure response"); } sshkey_free(key); - RSA_free(rsa); -#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) - EC_KEY_free(ecdsa); -#endif - free(data); - free(blob); + free(alg); free(signature); send_msg(msg); sshbuf_free(msg); @@ -301,10 +177,6 @@ process(void) debug("process_add"); process_add(); break; - case SSH_AGENTC_REMOVE_SMARTCARD_KEY: - debug("process_del"); - process_del(); - break; case SSH2_AGENTC_SIGN_REQUEST: debug("process_sign"); process_sign(); @@ -336,7 +208,6 @@ cleanup_exit(int i) _exit(i); } - int main(int argc, char **argv) { @@ -350,8 +221,9 @@ main(int argc, char **argv) __progname = ssh_get_progname(argv[0]); seed_rng(); - TAILQ_INIT(&pkcs11_keylist); + sanitise_stdfd(); + closefrom(STDERR_FILENO + 1); log_init(__progname, log_level, log_facility, log_stderr); while ((ch = getopt(argc, argv, "v")) != -1) { @@ -439,21 +311,6 @@ main(int argc, char **argv) fatal_fr(r, "reserve"); } } - -#else /* WITH_OPENSSL */ -void -cleanup_exit(int i) -{ - _exit(i); -} - -int -main(int argc, char **argv) -{ - fprintf(stderr, "PKCS#11 code is not enabled\n"); - return 1; -} -#endif /* WITH_OPENSSL */ #else /* ENABLE_PKCS11 */ int main(int argc, char **argv) diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c index fadf9c9..7a7d3b8 100644 --- a/ssh-pkcs11.c +++ b/ssh-pkcs11.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11.c,v 1.63 2024/08/15 00:51:51 djm Exp $ */ +/* $OpenBSD: ssh-pkcs11.c,v 1.78 2026/03/03 09:57:25 dtucker Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * Copyright (c) 2014 Pedro Martelletto. All rights reserved. @@ -20,34 +20,37 @@ #ifdef ENABLE_PKCS11 -#ifdef HAVE_SYS_TIME_H -# include -#endif +#include #include +#include #include #include -#include #include #include -#include "openbsd-compat/sys-queue.h" +#ifdef WITH_OPENSSL #include "openbsd-compat/openssl-compat.h" - +#include #include #include #include +#endif #define CRYPTOKI_COMPAT #include "pkcs11.h" +#define SSHKEY_INTERNAL +#include "sshkey.h" + #include "log.h" #include "misc.h" -#include "sshkey.h" +#include "sshbuf.h" #include "ssh-pkcs11.h" #include "digest.h" #include "xmalloc.h" +#include "crypto_api.h" struct pkcs11_slotinfo { CK_TOKEN_INFO token; @@ -71,15 +74,19 @@ struct pkcs11_provider { TAILQ_HEAD(, pkcs11_provider) pkcs11_providers; struct pkcs11_key { + struct sshbuf *keyblob; struct pkcs11_provider *provider; CK_ULONG slotidx; char *keyid; int keyid_len; + TAILQ_ENTRY(pkcs11_key) next; }; +TAILQ_HEAD(, pkcs11_key) pkcs11_keys; /* XXX a tree would be better */ + int pkcs11_interactive = 0; -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) +#if defined(OPENSSL_HAS_ECC) || defined(OPENSSL_HAS_ED25519) static void ossl_error(const char *msg) { @@ -89,15 +96,7 @@ ossl_error(const char *msg) while ((e = ERR_get_error()) != 0) error_f("libcrypto error: %s", ERR_error_string(e, NULL)); } -#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ - -int -pkcs11_init(int interactive) -{ - pkcs11_interactive = interactive; - TAILQ_INIT(&pkcs11_providers); - return (0); -} +#endif /* * finalize a provider shared library, it's no longer usable. @@ -146,19 +145,6 @@ pkcs11_provider_unref(struct pkcs11_provider *p) } } -/* unregister all providers, keys might still point to the providers */ -void -pkcs11_terminate(void) -{ - struct pkcs11_provider *p; - - while ((p = TAILQ_FIRST(&pkcs11_providers)) != NULL) { - TAILQ_REMOVE(&pkcs11_providers, p, next); - pkcs11_provider_finalize(p); - pkcs11_provider_unref(p); - } -} - /* lookup provider by name */ static struct pkcs11_provider * pkcs11_provider_lookup(char *provider_id) @@ -188,26 +174,16 @@ pkcs11_del_provider(char *provider_id) return (-1); } -static RSA_METHOD *rsa_method; -static int rsa_idx = 0; -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) -static EC_KEY_METHOD *ec_key_method; -static int ec_key_idx = 0; -#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ - /* release a wrapped object */ static void -pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, - long argl, void *argp) +pkcs11_k11_free(struct pkcs11_key *k11) { - struct pkcs11_key *k11 = ptr; - - debug_f("parent %p ptr %p idx %d", parent, ptr, idx); if (k11 == NULL) return; if (k11->provider) pkcs11_provider_unref(k11->provider); free(k11->keyid); + sshbuf_free(k11->keyblob); free(k11); } @@ -417,214 +393,384 @@ pkcs11_get_key(struct pkcs11_key *k11, CK_MECHANISM_TYPE mech_type) return (0); } -/* openssl callback doing the actual signing operation */ +/* record the key information later use lookup by keyblob */ static int -pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, - int padding) +pkcs11_record_key(struct pkcs11_provider *provider, CK_ULONG slotidx, + CK_ATTRIBUTE *keyid_attrib, struct sshkey *key) { - struct pkcs11_key *k11; - struct pkcs11_slotinfo *si; - CK_FUNCTION_LIST *f; - CK_ULONG tlen = 0; - CK_RV rv; - int rval = -1; - - if ((k11 = RSA_get_ex_data(rsa, rsa_idx)) == NULL) { - error("RSA_get_ex_data failed"); - return (-1); + struct sshbuf *keyblob; + struct pkcs11_key *k11; + int r; + char *hex; + + hex = tohex(keyid_attrib->pValue, keyid_attrib->ulValueLen); + debug_f("%s key: provider %s slot %lu keyid %s", + sshkey_type(key), provider->name, (u_long)slotidx, hex); + free(hex); + + if ((keyblob = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + if ((r = sshkey_putb(key, keyblob)) != 0) + fatal_fr(r, "sshkey_putb"); + + /* Check if we've already recorded this key in a different slot */ + TAILQ_FOREACH(k11, &pkcs11_keys, next) { + if (sshbuf_equals(k11->keyblob, keyblob) == 0) { + hex = tohex(k11->keyid, k11->keyid_len); + debug_f("Already seen this key at " + "provider %s slot %lu keyid %s", + k11->provider->name, k11->slotidx, hex); + free(hex); + sshbuf_free(keyblob); + return -1; + } } - if (pkcs11_get_key(k11, CKM_RSA_PKCS) == -1) { - error("pkcs11_get_key failed"); - return (-1); + k11 = xcalloc(1, sizeof(*k11)); + k11->provider = provider; + k11->keyblob = keyblob; + provider->refcount++; /* provider referenced by RSA key */ + k11->slotidx = slotidx; + /* identify key object on smartcard */ + k11->keyid_len = keyid_attrib->ulValueLen; + if (k11->keyid_len > 0) { + k11->keyid = xmalloc(k11->keyid_len); + memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); } + TAILQ_INSERT_TAIL(&pkcs11_keys, k11, next); - f = k11->provider->function_list; - si = &k11->provider->slotinfo[k11->slotidx]; - tlen = RSA_size(rsa); - - /* XXX handle CKR_BUFFER_TOO_SMALL */ - rv = f->C_Sign(si->session, (CK_BYTE *)from, flen, to, &tlen); - if (rv == CKR_OK) - rval = tlen; - else - error("C_Sign failed: %lu", rv); - - return (rval); + return 0; } -static int -pkcs11_rsa_private_decrypt(int flen, const u_char *from, u_char *to, RSA *rsa, - int padding) +/* retrieve the key information by keyblob */ +static struct pkcs11_key * +pkcs11_lookup_key(struct sshkey *key) { - return (-1); + struct pkcs11_key *k11, *found = NULL; + struct sshbuf *keyblob; + int r; + + if ((keyblob = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + if ((r = sshkey_putb(key, keyblob)) != 0) + fatal_fr(r, "sshkey_putb"); + TAILQ_FOREACH(k11, &pkcs11_keys, next) { + if (sshbuf_equals(k11->keyblob, keyblob) == 0) { + found = k11; + break; + } + } + sshbuf_free(keyblob); + return found; } +#ifdef WITH_OPENSSL +/* + * See: + * https://datatracker.ietf.org/doc/html/rfc8017#section-9.2 + */ + +/* + * id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) + * oiw(14) secsig(3) algorithms(2) 26 } + */ +static const u_char id_sha1[] = { + 0x30, 0x21, /* type Sequence, length 0x21 (33) */ + 0x30, 0x09, /* type Sequence, length 0x09 */ + 0x06, 0x05, /* type OID, length 0x05 */ + 0x2b, 0x0e, 0x03, 0x02, 0x1a, /* id-sha1 OID */ + 0x05, 0x00, /* NULL */ + 0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */ +}; + +/* + * id-sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) + * organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2) + * id-sha256(1) } + */ +static const u_char id_sha256[] = { + 0x30, 0x31, /* type Sequence, length 0x31 (49) */ + 0x30, 0x0d, /* type Sequence, length 0x0d (13) */ + 0x06, 0x09, /* type OID, length 0x09 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, /* id-sha256 */ + 0x05, 0x00, /* NULL */ + 0x04, 0x20 /* Octet string, length 0x20 (32), followed by sha256 hash */ +}; + +/* + * id-sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) + * organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2) + * id-sha256(3) } + */ +static const u_char id_sha512[] = { + 0x30, 0x51, /* type Sequence, length 0x51 (81) */ + 0x30, 0x0d, /* type Sequence, length 0x0d (13) */ + 0x06, 0x09, /* type OID, length 0x09 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, /* id-sha512 */ + 0x05, 0x00, /* NULL */ + 0x04, 0x40 /* Octet string, length 0x40 (64), followed by sha512 hash */ +}; + static int -pkcs11_rsa_start_wrapper(void) +rsa_hash_alg_oid(int hash_alg, const u_char **oidp, size_t *oidlenp) { - if (rsa_method != NULL) - return (0); - rsa_method = RSA_meth_dup(RSA_get_default_method()); - if (rsa_method == NULL) - return (-1); - rsa_idx = RSA_get_ex_new_index(0, "ssh-pkcs11-rsa", - NULL, NULL, pkcs11_k11_free); - if (rsa_idx == -1) - return (-1); - if (!RSA_meth_set1_name(rsa_method, "pkcs11") || - !RSA_meth_set_priv_enc(rsa_method, pkcs11_rsa_private_encrypt) || - !RSA_meth_set_priv_dec(rsa_method, pkcs11_rsa_private_decrypt)) { - error_f("setup pkcs11 method failed"); - return (-1); + switch (hash_alg) { + case SSH_DIGEST_SHA1: + *oidp = id_sha1; + *oidlenp = sizeof(id_sha1); + break; + case SSH_DIGEST_SHA256: + *oidp = id_sha256; + *oidlenp = sizeof(id_sha256); + break; + case SSH_DIGEST_SHA512: + *oidp = id_sha512; + *oidlenp = sizeof(id_sha512); + break; + default: + return SSH_ERR_INVALID_ARGUMENT; } - return (0); + return 0; } -/* redirect private key operations for rsa key to pkcs11 token */ static int -pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, - CK_ATTRIBUTE *keyid_attrib, RSA *rsa) +pkcs11_sign_rsa(struct sshkey *key, + u_char **sigp, size_t *lenp, + const u_char *data, size_t datalen, + const char *alg, const char *sk_provider, + const char *sk_pin, u_int compat) { struct pkcs11_key *k11; + struct pkcs11_slotinfo *si; + CK_FUNCTION_LIST *f; + CK_ULONG slen = 0; + CK_RV rv; + int hashalg, r, diff, siglen, ret = -1; + u_char *oid_dgst = NULL, *sig = NULL; + size_t dgst_len, oid_len, oid_dgst_len = 0; + const u_char *oid; - if (pkcs11_rsa_start_wrapper() == -1) - return (-1); + if (sigp != NULL) + *sigp = NULL; + if (lenp != NULL) + *lenp = 0; - k11 = xcalloc(1, sizeof(*k11)); - k11->provider = provider; - provider->refcount++; /* provider referenced by RSA key */ - k11->slotidx = slotidx; - /* identify key object on smartcard */ - k11->keyid_len = keyid_attrib->ulValueLen; - if (k11->keyid_len > 0) { - k11->keyid = xmalloc(k11->keyid_len); - memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); + if ((k11 = pkcs11_lookup_key(key)) == NULL) { + error_f("no key found"); + return SSH_ERR_KEY_NOT_FOUND; } - if (RSA_set_method(rsa, rsa_method) != 1) - fatal_f("RSA_set_method failed"); - if (RSA_set_ex_data(rsa, rsa_idx, k11) != 1) - fatal_f("RSA_set_ex_data failed"); - return (0); + debug3_f("sign with alg \"%s\" using provider %s slotidx %lu", + alg == NULL ? "" : alg, k11->provider->name, (u_long)k11->slotidx); + + if (pkcs11_get_key(k11, CKM_RSA_PKCS) == -1) { + error("pkcs11_get_key failed"); + return SSH_ERR_AGENT_FAILURE; + } + + f = k11->provider->function_list; + si = &k11->provider->slotinfo[k11->slotidx]; + + if ((siglen = EVP_PKEY_size(key->pkey)) <= 0) + return SSH_ERR_INVALID_ARGUMENT; + sig = xmalloc(siglen); + slen = (CK_ULONG)siglen; + + /* Determine hash algorithm and OID for signature */ + if (alg == NULL || *alg == '\0') + hashalg = SSH_DIGEST_SHA1; + else if ((hashalg = ssh_rsa_hash_id_from_keyname(alg)) == -1) + fatal_f("couldn't determine RSA hash alg \"%s\"", alg); + if ((r = rsa_hash_alg_oid(hashalg, &oid, &oid_len)) != 0) + fatal_fr(r, "rsa_hash_alg_oid failed"); + if ((dgst_len = ssh_digest_bytes(hashalg)) == 0) + fatal_f("bad hash alg %d", hashalg); + + /* Prepare { oid || digest } */ + oid_dgst_len = oid_len + dgst_len; + oid_dgst = xcalloc(1, oid_dgst_len); + memcpy(oid_dgst, oid, oid_len); + if ((r = ssh_digest_memory(hashalg, data, datalen, + oid_dgst + oid_len, dgst_len)) == -1) + fatal_fr(r, "hash failed"); + + /* XXX handle CKR_BUFFER_TOO_SMALL */ + if ((rv = f->C_Sign(si->session, (CK_BYTE *)oid_dgst, + oid_dgst_len, sig, &slen)) != CKR_OK) { + error("C_Sign failed: %lu", rv); + goto done; + } + + if (slen < (CK_ULONG)siglen) { + diff = siglen - slen; + debug3_f("repack %lu < %d (diff %d)", + (u_long)slen, siglen, diff); + memmove(sig + diff, sig, slen); + explicit_bzero(sig, diff); + } else if (slen > (size_t)siglen) + fatal_f("bad C_Sign length"); + + if ((ret = ssh_rsa_encode_store_sig(hashalg, sig, siglen, + sigp, lenp)) != 0) + fatal_fr(ret, "couldn't store signature"); + + /* success */ + ret = 0; + done: + freezero(oid_dgst, oid_dgst_len); + free(sig); + return ret; } -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) -/* openssl callback doing the actual signing operation */ -static ECDSA_SIG * -ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, - const BIGNUM *rp, EC_KEY *ec) +#ifdef OPENSSL_HAS_ECC +static int +pkcs11_sign_ecdsa(struct sshkey *key, + u_char **sigp, size_t *lenp, + const u_char *data, size_t datalen, + const char *alg, const char *sk_provider, + const char *sk_pin, u_int compat) { struct pkcs11_key *k11; struct pkcs11_slotinfo *si; CK_FUNCTION_LIST *f; - CK_ULONG siglen = 0, bnlen; + CK_ULONG slen = 0, bnlen; CK_RV rv; - ECDSA_SIG *ret = NULL; - u_char *sig; - BIGNUM *r = NULL, *s = NULL; + BIGNUM *sig_r = NULL, *sig_s = NULL; + u_char *sig = NULL, *dgst = NULL; + size_t dgst_len = 0; + int hashalg, ret = -1, r, siglen; - if ((k11 = EC_KEY_get_ex_data(ec, ec_key_idx)) == NULL) { - ossl_error("EC_KEY_get_ex_data failed for ec"); - return (NULL); + if (sigp != NULL) + *sigp = NULL; + if (lenp != NULL) + *lenp = 0; + + if ((k11 = pkcs11_lookup_key(key)) == NULL) { + error_f("no key found"); + return SSH_ERR_KEY_NOT_FOUND; } if (pkcs11_get_key(k11, CKM_ECDSA) == -1) { error("pkcs11_get_key failed"); - return (NULL); + return SSH_ERR_AGENT_FAILURE; } + debug3_f("sign using provider %s slotidx %lu", + k11->provider->name, (u_long)k11->slotidx); + f = k11->provider->function_list; si = &k11->provider->slotinfo[k11->slotidx]; - siglen = ECDSA_size(ec); + /* Prepare digest to be signed */ + if ((hashalg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1) + fatal_f("couldn't determine ECDSA hash alg"); + if ((dgst_len = ssh_digest_bytes(hashalg)) == 0) + fatal_f("bad hash alg %d", hashalg); + dgst = xcalloc(1, dgst_len); + if ((r = ssh_digest_memory(hashalg, data, datalen, + dgst, dgst_len)) == -1) + fatal_fr(r, "hash failed"); + + if ((siglen = EVP_PKEY_size(key->pkey)) <= 0) + return SSH_ERR_INVALID_ARGUMENT; sig = xmalloc(siglen); + slen = (CK_ULONG)siglen; /* XXX handle CKR_BUFFER_TOO_SMALL */ - rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dgst_len, sig, &siglen); + rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dgst_len, sig, &slen); if (rv != CKR_OK) { error("C_Sign failed: %lu", rv); goto done; } - if (siglen < 64 || siglen > 132 || siglen % 2) { - error_f("bad signature length: %lu", (u_long)siglen); + if (slen < 64 || slen > 132 || slen % 2) { + error_f("bad signature length: %lu", (u_long)slen); goto done; } - bnlen = siglen/2; - if ((ret = ECDSA_SIG_new()) == NULL) { - error("ECDSA_SIG_new failed"); - goto done; - } - if ((r = BN_bin2bn(sig, bnlen, NULL)) == NULL || - (s = BN_bin2bn(sig+bnlen, bnlen, NULL)) == NULL) { + bnlen = slen/2; + if ((sig_r = BN_bin2bn(sig, bnlen, NULL)) == NULL || + (sig_s = BN_bin2bn(sig+bnlen, bnlen, NULL)) == NULL) { ossl_error("BN_bin2bn failed"); - ECDSA_SIG_free(ret); - ret = NULL; goto done; } - if (!ECDSA_SIG_set0(ret, r, s)) { - error_f("ECDSA_SIG_set0 failed"); - ECDSA_SIG_free(ret); - ret = NULL; - goto done; - } - r = s = NULL; /* now owned by ret */ + + if ((ret = ssh_ecdsa_encode_store_sig(key, sig_r, sig_s, + sigp, lenp)) != 0) + fatal_fr(ret, "couldn't store signature"); + /* success */ + ret = 0; done: - BN_free(r); - BN_free(s); + freezero(dgst, dgst_len); + BN_free(sig_r); + BN_free(sig_s); free(sig); - - return (ret); + return ret; } +#endif /* OPENSSL_HAS_ECC */ +#endif /* WITH_OPENSSL */ static int -pkcs11_ecdsa_start_wrapper(void) +pkcs11_sign_ed25519(struct sshkey *key, + u_char **sigp, size_t *lenp, + const u_char *data, size_t datalen, + const char *alg, const char *sk_provider, + const char *sk_pin, u_int compat) { - int (*orig_sign)(int, const unsigned char *, int, unsigned char *, - unsigned int *, const BIGNUM *, const BIGNUM *, EC_KEY *) = NULL; + struct pkcs11_key *k11; + struct pkcs11_slotinfo *si; + CK_FUNCTION_LIST *f; + CK_ULONG slen = 0; + CK_RV rv; + u_char *sig = NULL; + CK_BYTE *xdata = NULL; + int ret = -1; - if (ec_key_method != NULL) - return (0); - ec_key_idx = EC_KEY_get_ex_new_index(0, "ssh-pkcs11-ecdsa", - NULL, NULL, pkcs11_k11_free); - if (ec_key_idx == -1) - return (-1); - ec_key_method = EC_KEY_METHOD_new(EC_KEY_OpenSSL()); - if (ec_key_method == NULL) - return (-1); - EC_KEY_METHOD_get_sign(ec_key_method, &orig_sign, NULL, NULL); - EC_KEY_METHOD_set_sign(ec_key_method, orig_sign, NULL, ecdsa_do_sign); - return (0); -} + if (sigp != NULL) + *sigp = NULL; + if (lenp != NULL) + *lenp = 0; -static int -pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, - CK_ATTRIBUTE *keyid_attrib, EC_KEY *ec) -{ - struct pkcs11_key *k11; + if ((k11 = pkcs11_lookup_key(key)) == NULL) { + error_f("no key found"); + return SSH_ERR_KEY_NOT_FOUND; + } - if (pkcs11_ecdsa_start_wrapper() == -1) - return (-1); + if (pkcs11_get_key(k11, CKM_EDDSA) == -1) { + error("pkcs11_get_key failed"); + return SSH_ERR_AGENT_FAILURE; + } - k11 = xcalloc(1, sizeof(*k11)); - k11->provider = provider; - provider->refcount++; /* provider referenced by ECDSA key */ - k11->slotidx = slotidx; - /* identify key object on smartcard */ - k11->keyid_len = keyid_attrib->ulValueLen; - if (k11->keyid_len > 0) { - k11->keyid = xmalloc(k11->keyid_len); - memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); + debug3_f("sign using provider %s slotidx %lu", + k11->provider->name, (u_long)k11->slotidx); + + f = k11->provider->function_list; + si = &k11->provider->slotinfo[k11->slotidx]; + + xdata = xmalloc(datalen); + memcpy(xdata, data, datalen); + sig = xmalloc(crypto_sign_ed25519_BYTES); + slen = crypto_sign_ed25519_BYTES; + + rv = f->C_Sign(si->session, xdata, datalen, sig, &slen); + if (rv != CKR_OK) { + error("C_Sign failed: %lu", rv); + goto done; } - if (EC_KEY_set_method(ec, ec_key_method) != 1) - fatal_f("EC_KEY_set_method failed"); - if (EC_KEY_set_ex_data(ec, ec_key_idx, k11) != 1) - fatal_f("EC_KEY_set_ex_data failed"); + if (slen != crypto_sign_ed25519_BYTES) { + error_f("bad signature length: %lu", (u_long)slen); + goto done; + } + if ((ret = ssh_ed25519_encode_store_sig(sig, slen, sigp, lenp)) != 0) + fatal_fr(ret, "couldn't store signature"); - return (0); + /* success */ + ret = 0; + done: + if (xdata != NULL) + freezero(xdata, datalen); + free(sig); + return ret; } -#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ /* remove trailing spaces */ static char * @@ -702,7 +848,8 @@ pkcs11_key_included(struct sshkey ***keysp, int *nkeys, struct sshkey *key) return (0); } -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) +#ifdef WITH_OPENSSL +#ifdef OPENSSL_HAS_ECC static struct sshkey * pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj) @@ -716,8 +863,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, EC_GROUP *group = NULL; struct sshkey *key = NULL; const unsigned char *attrp = NULL; - int i; - int nid; + int success = -1, r, i, nid; memset(&key_attr, 0, sizeof(key_attr)); key_attr[0].type = CKA_ID; @@ -786,11 +932,16 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, ossl_error("d2i_ASN1_OCTET_STRING failed"); goto fail; } - attrp = octet->data; - if (o2i_ECPublicKey(&ec, &attrp, octet->length) == NULL) { + attrp = ASN1_STRING_get0_data(octet); + if (o2i_ECPublicKey(&ec, &attrp, ASN1_STRING_length(octet)) == NULL) { ossl_error("o2i_ECPublicKey failed"); goto fail; } + if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(ec), + EC_KEY_get0_public_key(ec))) != 0) { + error_fr(r, "invalid EC key"); + goto fail; + } nid = sshkey_ecdsa_key_to_nid(ec); if (nid < 0) { @@ -798,9 +949,6 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } - if (pkcs11_ecdsa_wrap(p, slotidx, &key_attr[0], ec)) - goto fail; - key = sshkey_new(KEY_UNSPEC); if (key == NULL) { error("sshkey_new failed"); @@ -815,8 +963,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, key->ecdsa_nid = nid; key->type = KEY_ECDSA; key->flags |= SSHKEY_FLAG_EXT; - + if (pkcs11_record_key(p, slotidx, &key_attr[0], key)) + goto fail; + /* success */ + success = 0; fail: + if (success != 0) { + sshkey_free(key); + key = NULL; + } for (i = 0; i < 3; i++) free(key_attr[i].pValue); if (ec) @@ -828,7 +983,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, return (key); } -#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ +#endif /* OPENSSL_HAS_ECC */ static struct sshkey * pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, @@ -841,7 +996,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, RSA *rsa = NULL; BIGNUM *rsa_n, *rsa_e; struct sshkey *key = NULL; - int i; + int i, success = -1; memset(&key_attr, 0, sizeof(key_attr)); key_attr[0].type = CKA_ID; @@ -897,9 +1052,6 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, fatal_f("set key"); rsa_n = rsa_e = NULL; /* transferred */ - if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], rsa)) - goto fail; - key = sshkey_new(KEY_UNSPEC); if (key == NULL) { error("sshkey_new failed"); @@ -913,15 +1065,137 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, fatal("EVP_PKEY_set1_RSA failed"); key->type = KEY_RSA; key->flags |= SSHKEY_FLAG_EXT; - + if (EVP_PKEY_bits(key->pkey) < SSH_RSA_MINIMUM_MODULUS_SIZE) { + error_f("RSA key too small %d < minimum %d", + EVP_PKEY_bits(key->pkey), SSH_RSA_MINIMUM_MODULUS_SIZE); + goto fail; + } + if (pkcs11_record_key(p, slotidx, &key_attr[0], key)) + goto fail; + /* success */ + success = 0; fail: for (i = 0; i < 3; i++) free(key_attr[i].pValue); RSA_free(rsa); + if (success != 0) { + sshkey_free(key); + key = NULL; + } + return key; +} +#endif /* WITH_OPENSSL */ - return (key); +static struct sshkey * +pkcs11_fetch_ed25519_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + CK_OBJECT_HANDLE *obj) +{ + CK_ATTRIBUTE key_attr[3]; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; + struct sshkey *key = NULL; + const unsigned char *d = NULL; + size_t len; + char *hex = NULL; + int success = -1, i; + /* https://docs.oasis-open.org/pkcs11/pkcs11-curr/v3.0/os/pkcs11-curr-v3.0-os.html#_Toc30061180 */ + const u_char id1[14] = { + 0x13, 0x0c, 0x65, 0x64, 0x77, 0x61, 0x72, 0x64, + 0x73, 0x32, 0x35, 0x35, 0x31, 0x39, + }; /* PrintableString { "edwards25519" } */ + const u_char id2[5] = { + 0x06, 0x03, 0x2b, 0x65, 0x70, + }; /* OBJECT_IDENTIFIER { 1.3.101.112 } */ + + memset(&key_attr, 0, sizeof(key_attr)); + key_attr[0].type = CKA_ID; + key_attr[1].type = CKA_EC_POINT; /* XXX or CKA_VALUE ? */ + key_attr[2].type = CKA_EC_PARAMS; + + session = p->slotinfo[slotidx].session; + f = p->function_list; + + /* figure out size of the attributes */ + rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + return (NULL); + } + + /* + * Allow CKA_ID (always first attribute) to be empty, but + * ensure that none of the others are zero length. + * XXX assumes CKA_ID is always first. + */ + if (key_attr[1].ulValueLen == 0 || + key_attr[2].ulValueLen == 0) { + error("invalid attribute length"); + return (NULL); + } + + /* allocate buffers for attributes */ + for (i = 0; i < 3; i++) { + if (key_attr[i].ulValueLen > 0) + key_attr[i].pValue = xcalloc(1, key_attr[i].ulValueLen); + } + + /* retrieve ID, public point and curve parameters of EC key */ + rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + goto fail; + } + + /* Expect one of the supported identifiers in CKA_EC_PARAMS */ + d = (u_char *)key_attr[2].pValue; + len = key_attr[2].ulValueLen; + if ((len != sizeof(id1) || memcmp(d, id1, sizeof(id1)) != 0) && + (len != sizeof(id2) || memcmp(d, id2, sizeof(id2)) != 0)) { + hex = tohex(d, len); + logit_f("unsupported CKA_EC_PARAMS: %s (len %zu)", hex, len); + goto fail; + } + + /* + * Expect either a raw 32 byte pubkey or an OCTET STRING with + * a 32 byte pubkey in CKA_VALUE + */ + d = (u_char *)key_attr[1].pValue; + len = key_attr[1].ulValueLen; + if (len == ED25519_PK_SZ + 2 && d[0] == 0x04 && d[1] == ED25519_PK_SZ) { + d += 2; + len -= 2; + } + if (len != ED25519_PK_SZ) { + hex = tohex(key_attr[1].pValue, key_attr[1].ulValueLen); + logit_f("CKA_EC_POINT invalid octet str: %s (len %lu)", + hex, (u_long)key_attr[1].ulValueLen); + goto fail; + } + + if ((key = sshkey_new(KEY_UNSPEC)) == NULL) + fatal_f("sshkey_new failed"); + key->ed25519_pk = xmalloc(ED25519_PK_SZ); + memcpy(key->ed25519_pk, d, ED25519_PK_SZ); + key->type = KEY_ED25519; + key->flags |= SSHKEY_FLAG_EXT; + if (pkcs11_record_key(p, slotidx, &key_attr[0], key)) + goto fail; + /* success */ + success = 0; + fail: + if (success != 0) { + sshkey_free(key); + key = NULL; + } + free(hex); + for (i = 0; i < 3; i++) + free(key_attr[i].pValue); + return key; } +#ifdef WITH_OPENSSL static int pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj, struct sshkey **keyp, char **labelp) @@ -934,16 +1208,18 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, X509_NAME *x509_name = NULL; EVP_PKEY *evp; RSA *rsa = NULL; -#ifdef OPENSSL_HAS_ECC - EC_KEY *ec = NULL; -#endif + struct sshkey *key = NULL; - int i; -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) - int nid; -#endif + int i, success = -1; const u_char *cp; char *subject = NULL; +#ifdef OPENSSL_HAS_ED25519 + size_t len; +#endif /* OPENSSL_HAS_ED25519 */ +#ifdef OPENSSL_HAS_ECC + EC_KEY *ec = NULL; + int r, nid; +#endif *keyp = NULL; *labelp = NULL; @@ -1015,9 +1291,6 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto out; } - if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], rsa)) - goto out; - key = sshkey_new(KEY_UNSPEC); if (key == NULL) { error("sshkey_new failed"); @@ -1031,7 +1304,17 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, fatal("EVP_PKEY_set1_RSA failed"); key->type = KEY_RSA; key->flags |= SSHKEY_FLAG_EXT; -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) + if (EVP_PKEY_bits(key->pkey) < SSH_RSA_MINIMUM_MODULUS_SIZE) { + error_f("RSA key too small %d < minimum %d", + EVP_PKEY_bits(key->pkey), + SSH_RSA_MINIMUM_MODULUS_SIZE); + goto out; + } + if (pkcs11_record_key(p, slotidx, &cert_attr[0], key)) + goto out; + /* success */ + success = 0; +#ifdef OPENSSL_HAS_ECC } else if (EVP_PKEY_base_id(evp) == EVP_PKEY_EC) { if (EVP_PKEY_get0_EC_KEY(evp) == NULL) { error("invalid x509; no ec key"); @@ -1041,16 +1324,17 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, error("EC_KEY_dup failed"); goto out; } - + if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(ec), + EC_KEY_get0_public_key(ec))) != 0) { + error_fr(r, "invalid EC key"); + goto out; + } nid = sshkey_ecdsa_key_to_nid(ec); if (nid < 0) { error("couldn't get curve nid"); goto out; } - if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], ec)) - goto out; - key = sshkey_new(KEY_UNSPEC); if (key == NULL) { error("sshkey_new failed"); @@ -1065,7 +1349,33 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, key->ecdsa_nid = nid; key->type = KEY_ECDSA; key->flags |= SSHKEY_FLAG_EXT; -#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ + if (pkcs11_record_key(p, slotidx, &cert_attr[0], key)) + goto out; + /* success */ + success = 0; +#endif /* OPENSSL_HAS_ECC */ +#ifdef OPENSSL_HAS_ED25519 + } else if (EVP_PKEY_base_id(evp) == EVP_PKEY_ED25519) { + if ((key = sshkey_new(KEY_UNSPEC)) == NULL || + (key->ed25519_pk = calloc(1, ED25519_PK_SZ)) == NULL) + fatal_f("allocation failed"); + len = ED25519_PK_SZ; + if (!EVP_PKEY_get_raw_public_key(evp, key->ed25519_pk, &len)) { + ossl_error("EVP_PKEY_get_raw_public_key failed"); + goto out; + } + if (len != ED25519_PK_SZ) { + error_f("incorrect returned public key " + "length for ed25519"); + goto out; + } + key->type = KEY_ED25519; + key->flags |= SSHKEY_FLAG_EXT; + if (pkcs11_record_key(p, slotidx, &cert_attr[0], key)) + goto out; + /* success */ + success = 0; +#endif /* OPENSSL_HAS_ED25519 */ } else { error("unknown certificate key type"); goto out; @@ -1077,8 +1387,9 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, RSA_free(rsa); #ifdef OPENSSL_HAS_ECC EC_KEY_free(ec); -#endif - if (key == NULL) { +#endif /* OPENSSL_HAS_ECC */ + if (success != 0 || key == NULL) { + sshkey_free(key); free(subject); return -1; } @@ -1087,17 +1398,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, *labelp = subject; return 0; } - -#if 0 -static int -have_rsa_key(const RSA *rsa) -{ - const BIGNUM *rsa_n, *rsa_e; - - RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL); - return rsa_n != NULL && rsa_e != NULL; -} -#endif +#endif /* WITH_OPENSSL */ static void note_key(struct pkcs11_provider *p, CK_ULONG slotidx, const char *context, @@ -1115,6 +1416,7 @@ note_key(struct pkcs11_provider *p, CK_ULONG slotidx, const char *context, free(fp); } +#ifdef WITH_OPENSSL /* libcrypto needed for certificate parsing */ /* * lookup certificates for token in slot identified by slotidx, * add 'wrapped' public keys to the 'keysp' array and increment nkeys. @@ -1181,7 +1483,7 @@ pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, case CKC_X_509: if (pkcs11_fetch_x509_pubkey(p, slotidx, &obj, &key, &label) != 0) { - error("failed to fetch key"); + debug_f("failed to fetch key"); continue; } break; @@ -1192,7 +1494,7 @@ pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, } note_key(p, slotidx, __func__, key); if (pkcs11_key_included(keysp, nkeys, key)) { - debug2_f("key already included");; + debug2_f("key already included"); sshkey_free(key); } else { /* expand key array and add key */ @@ -1219,6 +1521,7 @@ pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, return (ret); } +#endif /* WITH_OPENSSL */ /* * lookup public keys for token in slot identified by slotidx, @@ -1286,27 +1589,33 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, label[key_attr[1].ulValueLen] = '\0'; switch (ck_key_type) { +#ifdef WITH_OPENSSL case CKK_RSA: key = pkcs11_fetch_rsa_pubkey(p, slotidx, &obj); break; -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) +#ifdef OPENSSL_HAS_ECC case CKK_ECDSA: key = pkcs11_fetch_ecdsa_pubkey(p, slotidx, &obj); break; -#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ +#endif /* OPENSSL_HAS_ECC */ +#endif /* WITH_OPENSSL */ + case CKK_EC_EDWARDS: + key = pkcs11_fetch_ed25519_pubkey(p, slotidx, &obj); + break; default: /* XXX print key type? */ key = NULL; - error("skipping unsupported key type"); + error("skipping unsupported key type 0x%lx", + (u_long)ck_key_type); } if (key == NULL) { - error("failed to fetch key"); + debug_f("failed to fetch key"); continue; } note_key(p, slotidx, __func__, key); if (pkcs11_key_included(keysp, nkeys, key)) { - debug2_f("key already included");; + debug2_f("key already included"); sshkey_free(key); } else { /* expand key array and add key */ @@ -1340,7 +1649,7 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, static struct sshkey * pkcs11_rsa_generate_private_key(struct pkcs11_provider *p, CK_ULONG slotidx, - char *label, CK_ULONG bits, CK_BYTE keyid, u_int32_t *err) + char *label, CK_ULONG bits, CK_BYTE keyid, uint32_t *err) { struct pkcs11_slotinfo *si; char *plabel = label ? label : ""; @@ -1431,7 +1740,7 @@ pkcs11_decode_hex(const char *hex, unsigned char **dest, size_t *rlen) *dest = xmalloc(len); for (i = 0; i < len; i++) { - int hi, low; + int hi, lo; hi = h2i(hex[2 * i]); lo = h2i(hex[(2 * i) + 1]); @@ -1460,7 +1769,7 @@ static struct ec_curve_info { static struct sshkey * pkcs11_ecdsa_generate_private_key(struct pkcs11_provider *p, CK_ULONG slotidx, - char *label, CK_ULONG bits, CK_BYTE keyid, u_int32_t *err) + char *label, CK_ULONG bits, CK_BYTE keyid, uint32_t *err) { struct pkcs11_slotinfo *si; char *plabel = label ? label : ""; @@ -1578,7 +1887,7 @@ pkcs11_register_provider(char *provider_id, char *pin, p = xcalloc(1, sizeof(*p)); p->name = xstrdup(provider_id); p->handle = handle; - /* setup the pkcs11 callbacks */ + /* set up the pkcs11 callbacks */ if ((rv = (*getfunctionlist)(&f)) != CKR_OK) { error("C_GetFunctionList for provider %s failed: %lu", provider_id, rv); @@ -1652,7 +1961,9 @@ pkcs11_register_provider(char *provider_id, char *pin, keyp == NULL) continue; pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); +#ifdef WITH_OPENSSL pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); +#endif if (nkeys == 0 && !p->slotinfo[i].logged_in && pkcs11_interactive) { /* @@ -1665,7 +1976,9 @@ pkcs11_register_provider(char *provider_id, char *pin, continue; } pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); +#ifdef WITH_OPENSSL pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); +#endif } } @@ -1693,6 +2006,37 @@ pkcs11_register_provider(char *provider_id, char *pin, return (ret); } +int +pkcs11_init(int interactive) +{ + debug3_f("called, interactive = %d", interactive); + + pkcs11_interactive = interactive; + TAILQ_INIT(&pkcs11_providers); + TAILQ_INIT(&pkcs11_keys); + return (0); +} + +/* unregister all providers, keys might still point to the providers */ +void +pkcs11_terminate(void) +{ + struct pkcs11_provider *p; + struct pkcs11_key *k11; + + debug3_f("called"); + + while ((k11 = TAILQ_FIRST(&pkcs11_keys)) != NULL) { + TAILQ_REMOVE(&pkcs11_keys, k11, next); + pkcs11_k11_free(k11); + } + while ((p = TAILQ_FIRST(&pkcs11_providers)) != NULL) { + TAILQ_REMOVE(&pkcs11_providers, p, next); + pkcs11_provider_finalize(p); + pkcs11_provider_unref(p); + } +} + /* * register a new provider and get number of keys hold by the token, * fails if provider already exists @@ -1719,10 +2063,45 @@ pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp, return (nkeys); } +int +pkcs11_sign(struct sshkey *key, + u_char **sigp, size_t *lenp, + const u_char *data, size_t datalen, + const char *alg, const char *sk_provider, + const char *sk_pin, u_int compat) +{ + switch (key->type) { + case KEY_RSA: + case KEY_RSA_CERT: +#ifdef WITH_OPENSSL + return pkcs11_sign_rsa(key, sigp, lenp, data, datalen, + alg, sk_provider, sk_pin, compat); +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: + case KEY_ECDSA_CERT: + return pkcs11_sign_ecdsa(key, sigp, lenp, data, datalen, + alg, sk_provider, sk_pin, compat); +#endif /* OPENSSL_HAS_ECC */ +#endif /* WITH_OPENSSL */ + case KEY_ED25519: + case KEY_ED25519_CERT: + return pkcs11_sign_ed25519(key, sigp, lenp, data, datalen, + alg, sk_provider, sk_pin, compat); + default: + return SSH_ERR_KEY_TYPE_UNKNOWN; + } +} + +void +pkcs11_key_free(struct sshkey *key) +{ + /* never called */ +} + #ifdef WITH_PKCS11_KEYGEN struct sshkey * pkcs11_gakp(char *provider_id, char *pin, unsigned int slotidx, char *label, - unsigned int type, unsigned int bits, unsigned char keyid, u_int32_t *err) + unsigned int type, unsigned int bits, unsigned char keyid, uint32_t *err) { struct pkcs11_provider *p = NULL; struct pkcs11_slotinfo *si; @@ -1788,7 +2167,7 @@ pkcs11_gakp(char *provider_id, char *pin, unsigned int slotidx, char *label, struct sshkey * pkcs11_destroy_keypair(char *provider_id, char *pin, unsigned long slotidx, - unsigned char keyid, u_int32_t *err) + unsigned char keyid, uint32_t *err) { struct pkcs11_provider *p = NULL; struct pkcs11_slotinfo *si; @@ -1862,10 +2241,24 @@ pkcs11_destroy_keypair(char *provider_id, char *pin, unsigned long slotidx, *err = rv; key_type = -1; } - if (key_type == CKK_RSA) + switch (key_type) { +#ifdef WITH_OPENSSL + case CKK_RSA: k = pkcs11_fetch_rsa_pubkey(p, slotidx, &obj); - else if (key_type == CKK_ECDSA) + break; +#ifdef OPENSSL_HAS_ECC + case CKK_ECDSA: k = pkcs11_fetch_ecdsa_pubkey(p, slotidx, &obj); + break; +#endif /* OPENSSL_HAS_ECC */ +#endif /* WITH_OPENSSL */ + case CKK_EC_EDWARDS: + k = pkcs11_fetch_ed25519_pubkey(p, slotidx, &obj); + break; + default: + debug_f("unsupported key type %lu", (u_long)key_type); + break; + } if ((rv = f->C_DestroyObject(session, obj)) != CKR_OK) { debug_f("could not destroy public key 0x%hhx", keyid); @@ -1893,11 +2286,13 @@ pkcs11_destroy_keypair(char *provider_id, char *pin, unsigned long slotidx, #include "log.h" #include "sshkey.h" +#include "ssherr.h" +#include "ssh-pkcs11.h" int pkcs11_init(int interactive) { - error("%s: dlopen() not supported", __func__); + error_f("PKCS#11 not supported"); return (-1); } @@ -1905,13 +2300,30 @@ int pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp, char ***labelsp) { - error("%s: dlopen() not supported", __func__); + error_f("PKCS#11 not supported"); return (-1); } +void +pkcs11_key_free(struct sshkey *key) +{ + error_f("PKCS#11 not supported"); +} + +int +pkcs11_sign(struct sshkey *key, + u_char **sigp, size_t *lenp, + const u_char *data, size_t datalen, + const char *alg, const char *sk_provider, + const char *sk_pin, u_int compat) +{ + error_f("PKCS#11 not supported"); + return SSH_ERR_FEATURE_UNSUPPORTED; +} + void pkcs11_terminate(void) { - error("%s: dlopen() not supported", __func__); + error_f("PKCS#11 not supported"); } #endif /* ENABLE_PKCS11 */ diff --git a/ssh-pkcs11.h b/ssh-pkcs11.h index 5260223..1d0277a 100644 --- a/ssh-pkcs11.h +++ b/ssh-pkcs11.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11.h,v 1.7 2023/12/18 14:46:56 djm Exp $ */ +/* $OpenBSD: ssh-pkcs11.h,v 1.11 2026/03/03 09:57:25 dtucker Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * @@ -15,6 +15,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +/* API for ssh-pkcs11.c and ssh-pkcs11-client.c */ + /* Errors for pkcs11_add_provider() */ #define SSH_PKCS11_ERR_GENERIC 1 #define SSH_PKCS11_ERR_LOGIN_FAIL 2 @@ -22,22 +24,26 @@ #define SSH_PKCS11_ERR_PIN_REQUIRED 4 #define SSH_PKCS11_ERR_PIN_LOCKED 5 +struct sshkey; + int pkcs11_init(int); void pkcs11_terminate(void); int pkcs11_add_provider(char *, char *, struct sshkey ***, char ***); int pkcs11_del_provider(char *); +int pkcs11_sign(struct sshkey *, u_char **, size_t *, + const u_char *, size_t, const char *, const char *, + const char *, u_int); +void pkcs11_key_free(struct sshkey *); + #ifdef WITH_PKCS11_KEYGEN struct sshkey * pkcs11_gakp(char *, char *, unsigned int, char *, unsigned int, - unsigned int, unsigned char, u_int32_t *); + unsigned int, unsigned char, uint32_t *); struct sshkey * pkcs11_destroy_keypair(char *, char *, unsigned long, unsigned char, - u_int32_t *); + uint32_t *); #endif -/* Only available in ssh-pkcs11-client.c so far */ +/* Only available in ssh-pkcs11-client.c */ int pkcs11_make_cert(const struct sshkey *, const struct sshkey *, struct sshkey **); -#if !defined(WITH_OPENSSL) && defined(ENABLE_PKCS11) -#undef ENABLE_PKCS11 -#endif diff --git a/ssh-rsa.c b/ssh-rsa.c index 3ad1fdd..ccadb14 100644 --- a/ssh-rsa.c +++ b/ssh-rsa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-rsa.c,v 1.80 2024/08/15 00:51:51 djm Exp $ */ +/* $OpenBSD: ssh-rsa.c,v 1.84 2026/02/14 00:18:34 jsg Exp $ */ /* * Copyright (c) 2000, 2003 Markus Friedl * @@ -18,11 +18,12 @@ #include "includes.h" #ifdef WITH_OPENSSL +#include "openbsd-compat/openssl-compat.h" #include +#include #include -#include #include #include @@ -32,9 +33,6 @@ #define SSHKEY_INTERNAL #include "sshkey.h" #include "digest.h" -#include "log.h" - -#include "openbsd-compat/openssl-compat.h" static u_int ssh_rsa_size(const struct sshkey *k) @@ -309,8 +307,8 @@ ssh_rsa_deserialize_private(const char *ktype, struct sshbuf *b, return r; } -static const char * -rsa_hash_alg_ident(int hash_alg) +const char * +ssh_rsa_hash_alg_ident(int hash_alg) { switch (hash_alg) { case SSH_DIGEST_SHA1: @@ -344,8 +342,8 @@ rsa_hash_id_from_ident(const char *ident) * all the cases of rsa_hash_id_from_ident() but also the certificate key * types. */ -static int -rsa_hash_id_from_keyname(const char *alg) +int +ssh_rsa_hash_id_from_keyname(const char *alg) { int r; @@ -410,7 +408,6 @@ ssh_rsa_sign(struct sshkey *key, size_t diff, len = 0; int slen = 0; int hash_alg, ret = SSH_ERR_INTERNAL_ERROR; - struct sshbuf *b = NULL; if (lenp != NULL) *lenp = 0; @@ -420,7 +417,7 @@ ssh_rsa_sign(struct sshkey *key, if (alg == NULL || strlen(alg) == 0) hash_alg = SSH_DIGEST_SHA1; else - hash_alg = rsa_hash_id_from_keyname(alg); + hash_alg = ssh_rsa_hash_id_from_keyname(alg); if (key == NULL || key->pkey == NULL || hash_alg == -1 || sshkey_type_plain(key->type) != KEY_RSA) @@ -442,16 +439,42 @@ ssh_rsa_sign(struct sshkey *key, ret = SSH_ERR_INTERNAL_ERROR; goto out; } + if ((ret = ssh_rsa_encode_store_sig(hash_alg, sig, slen, + sigp, lenp)) != 0) + goto out; + + /* success */ + ret = 0; + out: + freezero(sig, slen); + return ret; +} - /* encode signature */ +int +ssh_rsa_encode_store_sig(int hash_alg, const u_char *sig, size_t slen, + u_char **sigp, size_t *lenp) +{ + struct sshbuf *b = NULL; + int ret = SSH_ERR_INTERNAL_ERROR; + size_t len; + + if (lenp != NULL) + *lenp = 0; + if (sigp != NULL) + *sigp = NULL; + + /* Encode signature */ if ((b = sshbuf_new()) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } - if ((ret = sshbuf_put_cstring(b, rsa_hash_alg_ident(hash_alg))) != 0 || + if ((ret = sshbuf_put_cstring(b, + ssh_rsa_hash_alg_ident(hash_alg))) != 0 || (ret = sshbuf_put_string(b, sig, slen)) != 0) goto out; len = sshbuf_len(b); + + /* Store signature */ if (sigp != NULL) { if ((*sigp = malloc(len)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; @@ -463,7 +486,6 @@ ssh_rsa_sign(struct sshkey *key, *lenp = len; ret = 0; out: - freezero(sig, slen); sshbuf_free(b); return ret; } @@ -502,7 +524,7 @@ ssh_rsa_verify(const struct sshkey *key, * legacy reasons, but otherwise the signature type should match. */ if (alg != NULL && strcmp(alg, "ssh-rsa-cert-v01@openssh.com") != 0) { - if ((want_alg = rsa_hash_id_from_keyname(alg)) == -1) { + if ((want_alg = ssh_rsa_hash_id_from_keyname(alg)) == -1) { ret = SSH_ERR_INVALID_ARGUMENT; goto out; } diff --git a/ssh-sandbox.h b/ssh-sandbox.h index bd5fd83..3b74840 100644 --- a/ssh-sandbox.h +++ b/ssh-sandbox.h @@ -20,5 +20,3 @@ struct ssh_sandbox; struct ssh_sandbox *ssh_sandbox_init(struct monitor *); void ssh_sandbox_child(struct ssh_sandbox *); -void ssh_sandbox_parent_finish(struct ssh_sandbox *); -void ssh_sandbox_parent_preauth(struct ssh_sandbox *, pid_t); diff --git a/ssh-sk-client.c b/ssh-sk-client.c index 06fad22..52da28d 100644 --- a/ssh-sk-client.c +++ b/ssh-sk-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-sk-client.c,v 1.13 2025/02/18 08:02:48 djm Exp $ */ +/* $OpenBSD: ssh-sk-client.c,v 1.18 2026/03/11 09:10:59 dtucker Exp $ */ /* * Copyright (c) 2019 Google LLC * @@ -21,7 +21,6 @@ #include #include -#include #include #include #include @@ -30,13 +29,13 @@ #include #include #include +#include #include "log.h" #include "ssherr.h" #include "sshbuf.h" #include "sshkey.h" #include "msg.h" -#include "digest.h" #include "pathnames.h" #include "ssh-sk.h" #include "misc.h" @@ -47,9 +46,10 @@ static int start_helper(int *fdp, pid_t *pidp, void (**osigchldp)(int)) { void (*osigchld)(int); - int oerrno, pair[2]; + int oerrno, pair[2], execpipe[2]; + ssize_t n; pid_t pid; - char *helper, *verbosity = NULL; + char execbuf[100], *helper, *verbosity = NULL; *fdp = -1; *pidp = 0; @@ -58,19 +58,20 @@ start_helper(int *fdp, pid_t *pidp, void (**osigchldp)(int)) helper = getenv("SSH_SK_HELPER"); if (helper == NULL || strlen(helper) == 0) helper = _PATH_SSH_SK_HELPER; - if (access(helper, X_OK) != 0) { - oerrno = errno; - error_f("helper \"%s\" unusable: %s", helper, strerror(errno)); - errno = oerrno; - return SSH_ERR_SYSTEM_ERROR; - } #ifdef DEBUG_SK verbosity = "-vvv"; #endif + /* Create a O_CLOEXEC pipe to capture the execve() failure */ + if (pipe(execpipe) == -1) { + error("pipe: %s", strerror(errno)); + return SSH_ERR_SYSTEM_ERROR; + } /* Start helper */ if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) { error("socketpair: %s", strerror(errno)); + close(execpipe[0]); + close(execpipe[1]); return SSH_ERR_SYSTEM_ERROR; } osigchld = ssh_signal(SIGCHLD, SIG_DFL); @@ -79,14 +80,20 @@ start_helper(int *fdp, pid_t *pidp, void (**osigchldp)(int)) error("fork: %s", strerror(errno)); close(pair[0]); close(pair[1]); + close(execpipe[0]); + close(execpipe[1]); ssh_signal(SIGCHLD, osigchld); errno = oerrno; return SSH_ERR_SYSTEM_ERROR; } if (pid == 0) { + close(execpipe[0]); + FD_CLOSEONEXEC(execpipe[1]); if ((dup2(pair[1], STDIN_FILENO) == -1) || (dup2(pair[1], STDOUT_FILENO) == -1)) { - error_f("dup2: %s", strerror(errno)); + snprintf(execbuf, sizeof execbuf, + "dup2: %s", strerror(errno)); + write(execpipe[1], execbuf, strlen(execbuf)+1); _exit(1); } close(pair[0]); @@ -95,11 +102,22 @@ start_helper(int *fdp, pid_t *pidp, void (**osigchldp)(int)) debug_f("starting %s %s", helper, verbosity == NULL ? "" : verbosity); execlp(helper, helper, verbosity, (char *)NULL); - error_f("execlp: %s", strerror(errno)); + snprintf(execbuf, sizeof execbuf, + "execlp: %s", strerror(errno)); + write(execpipe[1], execbuf, strlen(execbuf)+1); _exit(1); } close(pair[1]); + close(execpipe[1]); + n = read(execpipe[0], execbuf, sizeof execbuf); + close(execpipe[0]); + if (n > 0) { + execbuf[n - 1] = '\0'; + error_f("%s", execbuf); + return SSH_ERR_AGENT_FAILURE; + } + /* success */ debug3_f("started pid=%ld", (long)pid); *fdp = pair[0]; diff --git a/ssh-sk-helper.0 b/ssh-sk-helper.0 index 9dc341c..886eac9 100644 --- a/ssh-sk-helper.0 +++ b/ssh-sk-helper.0 @@ -31,4 +31,4 @@ HISTORY AUTHORS Damien Miller -OpenBSD 7.6 April 29, 2022 OpenBSD 7.6 +OpenBSD 7.8 April 29, 2022 SSH-SK-HELPER(8) diff --git a/ssh-sk-helper.c b/ssh-sk-helper.c index 9857b63..7a87912 100644 --- a/ssh-sk-helper.c +++ b/ssh-sk-helper.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-sk-helper.c,v 1.14 2022/12/04 11:03:11 dtucker Exp $ */ +/* $OpenBSD: ssh-sk-helper.c,v 1.15 2025/07/24 05:44:55 djm Exp $ */ /* * Copyright (c) 2019 Google LLC * @@ -45,6 +45,7 @@ #include "uidswap.h" #include "ssherr.h" #include "ssh-sk.h" +#include "ssh-pkcs11.h" #ifdef ENABLE_SK extern char *__progname; @@ -87,6 +88,22 @@ null_empty(char **s) *s = NULL; } +/* stubs */ +int +pkcs11_sign(struct sshkey *key, + u_char **sigp, size_t *lenp, + const u_char *data, size_t datalen, + const char *alg, const char *sk_provider, + const char *sk_pin, u_int compat) +{ + return SSH_ERR_INTERNAL_ERROR; +} + +void +pkcs11_key_free(struct sshkey *key) +{ +} + static struct sshbuf * process_sign(struct sshbuf *req) { @@ -356,7 +373,6 @@ main(int argc, char **argv) return (0); } #else /* ENABLE_SK */ -#include int main(int argc, char **argv) diff --git a/ssh-sk.c b/ssh-sk.c index a2a7d72..6bb1edc 100644 --- a/ssh-sk.c +++ b/ssh-sk.c @@ -23,9 +23,7 @@ #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include diff --git a/ssh-xmss.c b/ssh-xmss.c deleted file mode 100644 index b6d0561..0000000 --- a/ssh-xmss.c +++ /dev/null @@ -1,389 +0,0 @@ -/* $OpenBSD: ssh-xmss.c,v 1.14 2022/10/28 00:44:44 djm Exp $*/ -/* - * Copyright (c) 2017 Stefan-Lukas Gazdag. - * Copyright (c) 2017 Markus Friedl. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, 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. - */ -#include "includes.h" -#ifdef WITH_XMSS - -#define SSHKEY_INTERNAL -#include -#include - -#include -#include -#include -#ifdef HAVE_STDINT_H -# include -#endif -#include - -#include "log.h" -#include "sshbuf.h" -#include "sshkey.h" -#include "sshkey-xmss.h" -#include "ssherr.h" -#include "ssh.h" - -#include "xmss_fast.h" - -static void -ssh_xmss_cleanup(struct sshkey *k) -{ - freezero(k->xmss_pk, sshkey_xmss_pklen(k)); - freezero(k->xmss_sk, sshkey_xmss_sklen(k)); - sshkey_xmss_free_state(k); - free(k->xmss_name); - free(k->xmss_filename); - k->xmss_pk = NULL; - k->xmss_sk = NULL; - k->xmss_name = NULL; - k->xmss_filename = NULL; -} - -static int -ssh_xmss_equal(const struct sshkey *a, const struct sshkey *b) -{ - if (a->xmss_pk == NULL || b->xmss_pk == NULL) - return 0; - if (sshkey_xmss_pklen(a) != sshkey_xmss_pklen(b)) - return 0; - if (memcmp(a->xmss_pk, b->xmss_pk, sshkey_xmss_pklen(a)) != 0) - return 0; - return 1; -} - -static int -ssh_xmss_serialize_public(const struct sshkey *key, struct sshbuf *b, - enum sshkey_serialize_rep opts) -{ - int r; - - if (key->xmss_name == NULL || key->xmss_pk == NULL || - sshkey_xmss_pklen(key) == 0) - return SSH_ERR_INVALID_ARGUMENT; - if ((r = sshbuf_put_cstring(b, key->xmss_name)) != 0 || - (r = sshbuf_put_string(b, key->xmss_pk, - sshkey_xmss_pklen(key))) != 0 || - (r = sshkey_xmss_serialize_pk_info(key, b, opts)) != 0) - return r; - - return 0; -} - -static int -ssh_xmss_serialize_private(const struct sshkey *key, struct sshbuf *b, - enum sshkey_serialize_rep opts) -{ - int r; - - if (key->xmss_name == NULL) - return SSH_ERR_INVALID_ARGUMENT; - /* Note: can't reuse ssh_xmss_serialize_public because of sk order */ - if ((r = sshbuf_put_cstring(b, key->xmss_name)) != 0 || - (r = sshbuf_put_string(b, key->xmss_pk, - sshkey_xmss_pklen(key))) != 0 || - (r = sshbuf_put_string(b, key->xmss_sk, - sshkey_xmss_sklen(key))) != 0 || - (r = sshkey_xmss_serialize_state_opt(key, b, opts)) != 0) - return r; - - return 0; -} - -static int -ssh_xmss_copy_public(const struct sshkey *from, struct sshkey *to) -{ - int r = SSH_ERR_INTERNAL_ERROR; - u_int32_t left; - size_t pklen; - - if ((r = sshkey_xmss_init(to, from->xmss_name)) != 0) - return r; - if (from->xmss_pk == NULL) - return 0; /* XXX SSH_ERR_INTERNAL_ERROR ? */ - - if ((pklen = sshkey_xmss_pklen(from)) == 0 || - sshkey_xmss_pklen(to) != pklen) - return SSH_ERR_INTERNAL_ERROR; - if ((to->xmss_pk = malloc(pklen)) == NULL) - return SSH_ERR_ALLOC_FAIL; - memcpy(to->xmss_pk, from->xmss_pk, pklen); - /* simulate number of signatures left on pubkey */ - left = sshkey_xmss_signatures_left(from); - if (left) - sshkey_xmss_enable_maxsign(to, left); - return 0; -} - -static int -ssh_xmss_deserialize_public(const char *ktype, struct sshbuf *b, - struct sshkey *key) -{ - size_t len = 0; - char *xmss_name = NULL; - u_char *pk = NULL; - int ret = SSH_ERR_INTERNAL_ERROR; - - if ((ret = sshbuf_get_cstring(b, &xmss_name, NULL)) != 0) - goto out; - if ((ret = sshkey_xmss_init(key, xmss_name)) != 0) - goto out; - if ((ret = sshbuf_get_string(b, &pk, &len)) != 0) - goto out; - if (len == 0 || len != sshkey_xmss_pklen(key)) { - ret = SSH_ERR_INVALID_FORMAT; - goto out; - } - key->xmss_pk = pk; - pk = NULL; - if (!sshkey_is_cert(key) && - (ret = sshkey_xmss_deserialize_pk_info(key, b)) != 0) - goto out; - /* success */ - ret = 0; - out: - free(xmss_name); - freezero(pk, len); - return ret; -} - -static int -ssh_xmss_deserialize_private(const char *ktype, struct sshbuf *b, - struct sshkey *key) -{ - int r; - char *xmss_name = NULL; - size_t pklen = 0, sklen = 0; - u_char *xmss_pk = NULL, *xmss_sk = NULL; - - /* Note: can't reuse ssh_xmss_deserialize_public because of sk order */ - if ((r = sshbuf_get_cstring(b, &xmss_name, NULL)) != 0 || - (r = sshbuf_get_string(b, &xmss_pk, &pklen)) != 0 || - (r = sshbuf_get_string(b, &xmss_sk, &sklen)) != 0) - goto out; - if (!sshkey_is_cert(key) && - (r = sshkey_xmss_init(key, xmss_name)) != 0) - goto out; - if (pklen != sshkey_xmss_pklen(key) || - sklen != sshkey_xmss_sklen(key)) { - r = SSH_ERR_INVALID_FORMAT; - goto out; - } - key->xmss_pk = xmss_pk; - key->xmss_sk = xmss_sk; - xmss_pk = xmss_sk = NULL; - /* optional internal state */ - if ((r = sshkey_xmss_deserialize_state_opt(key, b)) != 0) - goto out; - /* success */ - r = 0; - out: - free(xmss_name); - freezero(xmss_pk, pklen); - freezero(xmss_sk, sklen); - return r; -} - -static int -ssh_xmss_sign(struct sshkey *key, - u_char **sigp, size_t *lenp, - const u_char *data, size_t datalen, - const char *alg, const char *sk_provider, const char *sk_pin, u_int compat) -{ - u_char *sig = NULL; - size_t slen = 0, len = 0, required_siglen; - unsigned long long smlen; - int r, ret; - struct sshbuf *b = NULL; - - if (lenp != NULL) - *lenp = 0; - if (sigp != NULL) - *sigp = NULL; - - if (key == NULL || - sshkey_type_plain(key->type) != KEY_XMSS || - key->xmss_sk == NULL || - sshkey_xmss_params(key) == NULL) - return SSH_ERR_INVALID_ARGUMENT; - if ((r = sshkey_xmss_siglen(key, &required_siglen)) != 0) - return r; - if (datalen >= INT_MAX - required_siglen) - return SSH_ERR_INVALID_ARGUMENT; - smlen = slen = datalen + required_siglen; - if ((sig = malloc(slen)) == NULL) - return SSH_ERR_ALLOC_FAIL; - if ((r = sshkey_xmss_get_state(key, 1)) != 0) - goto out; - if ((ret = xmss_sign(key->xmss_sk, sshkey_xmss_bds_state(key), sig, &smlen, - data, datalen, sshkey_xmss_params(key))) != 0 || smlen <= datalen) { - r = SSH_ERR_INVALID_ARGUMENT; /* XXX better error? */ - goto out; - } - /* encode signature */ - if ((b = sshbuf_new()) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto out; - } - if ((r = sshbuf_put_cstring(b, "ssh-xmss@openssh.com")) != 0 || - (r = sshbuf_put_string(b, sig, smlen - datalen)) != 0) - goto out; - len = sshbuf_len(b); - if (sigp != NULL) { - if ((*sigp = malloc(len)) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto out; - } - memcpy(*sigp, sshbuf_ptr(b), len); - } - if (lenp != NULL) - *lenp = len; - /* success */ - r = 0; - out: - if ((ret = sshkey_xmss_update_state(key, 1)) != 0) { - /* discard signature since we cannot update the state */ - if (r == 0 && sigp != NULL && *sigp != NULL) { - explicit_bzero(*sigp, len); - free(*sigp); - } - if (sigp != NULL) - *sigp = NULL; - if (lenp != NULL) - *lenp = 0; - r = ret; - } - sshbuf_free(b); - if (sig != NULL) - freezero(sig, slen); - - return r; -} - -static int -ssh_xmss_verify(const struct sshkey *key, - const u_char *sig, size_t siglen, - const u_char *data, size_t dlen, const char *alg, u_int compat, - struct sshkey_sig_details **detailsp) -{ - struct sshbuf *b = NULL; - char *ktype = NULL; - const u_char *sigblob; - u_char *sm = NULL, *m = NULL; - size_t len, required_siglen; - unsigned long long smlen = 0, mlen = 0; - int r, ret; - - if (key == NULL || - sshkey_type_plain(key->type) != KEY_XMSS || - key->xmss_pk == NULL || - sshkey_xmss_params(key) == NULL || - sig == NULL || siglen == 0) - return SSH_ERR_INVALID_ARGUMENT; - if ((r = sshkey_xmss_siglen(key, &required_siglen)) != 0) - return r; - if (dlen >= INT_MAX - required_siglen) - return SSH_ERR_INVALID_ARGUMENT; - - if ((b = sshbuf_from(sig, siglen)) == NULL) - return SSH_ERR_ALLOC_FAIL; - if ((r = sshbuf_get_cstring(b, &ktype, NULL)) != 0 || - (r = sshbuf_get_string_direct(b, &sigblob, &len)) != 0) - goto out; - if (strcmp("ssh-xmss@openssh.com", ktype) != 0) { - r = SSH_ERR_KEY_TYPE_MISMATCH; - goto out; - } - if (sshbuf_len(b) != 0) { - r = SSH_ERR_UNEXPECTED_TRAILING_DATA; - goto out; - } - if (len != required_siglen) { - r = SSH_ERR_INVALID_FORMAT; - goto out; - } - if (dlen >= SIZE_MAX - len) { - r = SSH_ERR_INVALID_ARGUMENT; - goto out; - } - smlen = len + dlen; - mlen = smlen; - if ((sm = malloc(smlen)) == NULL || (m = malloc(mlen)) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto out; - } - memcpy(sm, sigblob, len); - memcpy(sm+len, data, dlen); - if ((ret = xmss_sign_open(m, &mlen, sm, smlen, - key->xmss_pk, sshkey_xmss_params(key))) != 0) { - debug2_f("xmss_sign_open failed: %d", ret); - } - if (ret != 0 || mlen != dlen) { - r = SSH_ERR_SIGNATURE_INVALID; - goto out; - } - /* XXX compare 'm' and 'data' ? */ - /* success */ - r = 0; - out: - if (sm != NULL) - freezero(sm, smlen); - if (m != NULL) - freezero(m, smlen); - sshbuf_free(b); - free(ktype); - return r; -} - -static const struct sshkey_impl_funcs sshkey_xmss_funcs = { - /* .size = */ NULL, - /* .alloc = */ NULL, - /* .cleanup = */ ssh_xmss_cleanup, - /* .equal = */ ssh_xmss_equal, - /* .ssh_serialize_public = */ ssh_xmss_serialize_public, - /* .ssh_deserialize_public = */ ssh_xmss_deserialize_public, - /* .ssh_serialize_private = */ ssh_xmss_serialize_private, - /* .ssh_deserialize_private = */ ssh_xmss_deserialize_private, - /* .generate = */ sshkey_xmss_generate_private_key, - /* .copy_public = */ ssh_xmss_copy_public, - /* .sign = */ ssh_xmss_sign, - /* .verify = */ ssh_xmss_verify, -}; - -const struct sshkey_impl sshkey_xmss_impl = { - /* .name = */ "ssh-xmss@openssh.com", - /* .shortname = */ "XMSS", - /* .sigalg = */ NULL, - /* .type = */ KEY_XMSS, - /* .nid = */ 0, - /* .cert = */ 0, - /* .sigonly = */ 0, - /* .keybits = */ 256, - /* .funcs = */ &sshkey_xmss_funcs, -}; - -const struct sshkey_impl sshkey_xmss_cert_impl = { - /* .name = */ "ssh-xmss-cert-v01@openssh.com", - /* .shortname = */ "XMSS-CERT", - /* .sigalg = */ NULL, - /* .type = */ KEY_XMSS_CERT, - /* .nid = */ 0, - /* .cert = */ 1, - /* .sigonly = */ 0, - /* .keybits = */ 256, - /* .funcs = */ &sshkey_xmss_funcs, -}; -#endif /* WITH_XMSS */ diff --git a/ssh.0 b/ssh.0 index 5ab1bc8..04e0e1c 100644 --- a/ssh.0 +++ b/ssh.0 @@ -17,7 +17,7 @@ DESCRIPTION ssh (SSH client) is a program for logging into a remote machine and for executing commands on a remote machine. It is intended to provide secure encrypted communications between two untrusted hosts over an insecure - network. X11 connections, arbitrary TCP ports and UNIX-domain sockets + network. X11 connections, arbitrary TCP ports and Unix-domain sockets can also be forwarded over the secure channel. ssh connects and logs into the specified destination, which may be @@ -43,7 +43,7 @@ DESCRIPTION Agent forwarding should be enabled with caution. Users with the ability to bypass file permissions on the remote host (for the - agent's UNIX-domain socket) can access the local agent through + agent's Unix-domain socket) can access the local agent through the forwarded connection. An attacker cannot obtain key material from the agent, however they can perform operations on the keys that enable them to authenticate using the identities loaded into @@ -63,7 +63,7 @@ DESCRIPTION address. -C Requests compression of all data (including stdin, stdout, - stderr, and data for forwarded X11, TCP and UNIX-domain + stderr, and data for forwarded X11, TCP and Unix-domain connections). The compression algorithm is the same used by gzip(1). Compression is desirable on modem lines and other slow connections, but will only slow down things on fast networks. @@ -232,12 +232,13 @@ DESCRIPTION Control an active connection multiplexing master process. When the -O option is specified, the ctl_cmd argument is interpreted and passed to the master process. Valid commands are: M-bM-^@M-^\checkM-bM-^@M-^] - (check that the master process is running), M-bM-^@M-^\forwardM-bM-^@M-^] (request - forwardings without command execution), M-bM-^@M-^\cancelM-bM-^@M-^] (cancel - forwardings), M-bM-^@M-^\proxyM-bM-^@M-^] (connect to a running multiplexing master - in proxy mode), M-bM-^@M-^\exitM-bM-^@M-^] (request the master to exit), and M-bM-^@M-^\stopM-bM-^@M-^] - (request the master to stop accepting further multiplexing - requests). + (check that the master process is running), M-bM-^@M-^\conninfoM-bM-^@M-^] (report + information about the master connection), M-bM-^@M-^\channelsM-bM-^@M-^] (report + information about open channels), M-bM-^@M-^\forwardM-bM-^@M-^] (request forwardings + without command execution), M-bM-^@M-^\cancelM-bM-^@M-^] (cancel forwardings), + M-bM-^@M-^\proxyM-bM-^@M-^] (connect to a running multiplexing master in proxy mode), + M-bM-^@M-^\exitM-bM-^@M-^] (request the master to exit), and M-bM-^@M-^\stopM-bM-^@M-^] (request the + master to stop accepting further multiplexing requests). -o option Can be used to give options in the format used in the @@ -250,24 +251,27 @@ DESCRIPTION AddressFamily BatchMode BindAddress + BindInterface + CASignatureAlgorithms CanonicalDomains CanonicalizeFallbackLocal CanonicalizeHostname CanonicalizeMaxDots CanonicalizePermittedCNAMEs - CASignatureAlgorithms CertificateFile + ChannelTimeout CheckHostIP Ciphers ClearAllForwardings Compression - ConnectionAttempts ConnectTimeout + ConnectionAttempts ControlMaster ControlPath ControlPersist DynamicForward EnableEscapeCommandline + EnableSSHKeysign EscapeChar ExitOnForwardFailure FingerprintHash @@ -276,21 +280,23 @@ DESCRIPTION ForwardX11 ForwardX11Timeout ForwardX11Trusted - GatewayPorts - GlobalKnownHostsFile GSSAPIAuthentication GSSAPIDelegateCredentials + GatewayPorts + GlobalKnownHostsFile HashKnownHosts Host - HostbasedAcceptedAlgorithms - HostbasedAuthentication HostKeyAlgorithms HostKeyAlias + HostbasedAcceptedAlgorithms + HostbasedAuthentication Hostname + IPQoS IdentitiesOnly IdentityAgent IdentityFile - IPQoS + IgnoreUnknown + Include KbdInteractiveAuthentication KbdInteractiveDevices KexAlgorithms @@ -298,14 +304,15 @@ DESCRIPTION LocalCommand LocalForward LogLevel + LogVerbose MACs - Match NoHostAuthenticationForLocalhost NumberOfPasswordPrompts + ObscureKeystrokeTiming + PKCS11Provider PasswordAuthentication PermitLocalCommand PermitRemoteOpen - PKCS11Provider Port PreferredAuthentications ProxyCommand @@ -318,16 +325,20 @@ DESCRIPTION RemoteForward RequestTTY RequiredRSASize + RevokedHostKeys + SecurityKeyProvider SendEnv - ServerAliveInterval ServerAliveCountMax + ServerAliveInterval SessionType SetEnv StdinNull StreamLocalBindMask StreamLocalBindUnlink StrictHostKeyChecking + SyslogFacility TCPKeepAlive + Tag Tunnel TunnelDevice UpdateHostKeys @@ -618,6 +629,8 @@ ESCAPE CHARACTERS PermitLocalCommand option is enabled in ssh_config(5). Basic help is available, using the -h option. + ~I Show information about the current SSH connection. + ~R Request rekeying of the connection (only useful if the peer supports it). @@ -818,7 +831,7 @@ ENVIRONMENT all passphrase input regardless of whether DISPLAY is set. - SSH_AUTH_SOCK Identifies the path of a UNIX-domain socket used to + SSH_AUTH_SOCK Identifies the path of a Unix-domain socket used to communicate with the agent. SSH_CONNECTION Identifies the client and server ends of the @@ -1017,4 +1030,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 7.6 July 18, 2024 OpenBSD 7.6 +OpenBSD 7.8 December 22, 2025 SSH(1) diff --git a/ssh.1 b/ssh.1 index 710d3d4..82ae548 100644 --- a/ssh.1 +++ b/ssh.1 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.443 2024/07/18 01:47:27 djm Exp $ -.Dd $Mdocdate: July 18 2024 $ +.\" $OpenBSD: ssh.1,v 1.447 2025/12/22 01:17:31 djm Exp $ +.Dd $Mdocdate: December 22 2025 $ .Dt SSH 1 .Os .Sh NAME @@ -486,6 +486,10 @@ argument is interpreted and passed to the master process. Valid commands are: .Dq check (check that the master process is running), +.Dq conninfo +(report information about the master connection), +.Dq channels +(report information about open channels), .Dq forward (request forwardings without command execution), .Dq cancel @@ -509,24 +513,27 @@ For full details of the options listed below, and their possible values, see .It AddressFamily .It BatchMode .It BindAddress +.It BindInterface +.It CASignatureAlgorithms .It CanonicalDomains .It CanonicalizeFallbackLocal .It CanonicalizeHostname .It CanonicalizeMaxDots .It CanonicalizePermittedCNAMEs -.It CASignatureAlgorithms .It CertificateFile +.It ChannelTimeout .It CheckHostIP .It Ciphers .It ClearAllForwardings .It Compression -.It ConnectionAttempts .It ConnectTimeout +.It ConnectionAttempts .It ControlMaster .It ControlPath .It ControlPersist .It DynamicForward .It EnableEscapeCommandline +.It EnableSSHKeysign .It EscapeChar .It ExitOnForwardFailure .It FingerprintHash @@ -535,21 +542,23 @@ For full details of the options listed below, and their possible values, see .It ForwardX11 .It ForwardX11Timeout .It ForwardX11Trusted -.It GatewayPorts -.It GlobalKnownHostsFile .It GSSAPIAuthentication .It GSSAPIDelegateCredentials +.It GatewayPorts +.It GlobalKnownHostsFile .It HashKnownHosts .It Host -.It HostbasedAcceptedAlgorithms -.It HostbasedAuthentication .It HostKeyAlgorithms .It HostKeyAlias +.It HostbasedAcceptedAlgorithms +.It HostbasedAuthentication .It Hostname +.It IPQoS .It IdentitiesOnly .It IdentityAgent .It IdentityFile -.It IPQoS +.It IgnoreUnknown +.It Include .It KbdInteractiveAuthentication .It KbdInteractiveDevices .It KexAlgorithms @@ -557,14 +566,15 @@ For full details of the options listed below, and their possible values, see .It LocalCommand .It LocalForward .It LogLevel +.It LogVerbose .It MACs -.It Match .It NoHostAuthenticationForLocalhost .It NumberOfPasswordPrompts +.It ObscureKeystrokeTiming +.It PKCS11Provider .It PasswordAuthentication .It PermitLocalCommand .It PermitRemoteOpen -.It PKCS11Provider .It Port .It PreferredAuthentications .It ProxyCommand @@ -577,16 +587,20 @@ For full details of the options listed below, and their possible values, see .It RemoteForward .It RequestTTY .It RequiredRSASize +.It RevokedHostKeys +.It SecurityKeyProvider .It SendEnv -.It ServerAliveInterval .It ServerAliveCountMax +.It ServerAliveInterval .It SessionType .It SetEnv .It StdinNull .It StreamLocalBindMask .It StreamLocalBindUnlink .It StrictHostKeyChecking +.It SyslogFacility .It TCPKeepAlive +.It Tag .It Tunnel .It TunnelDevice .It UpdateHostKeys @@ -1146,6 +1160,8 @@ option is enabled in Basic help is available, using the .Fl h option. +.It Cm ~I +Show information about the current SSH connection. .It Cm ~R Request rekeying of the connection (only useful if the peer supports it). diff --git a/ssh.c b/ssh.c index 0019281..531f28e 100644 --- a/ssh.c +++ b/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.600 2024/01/11 01:45:36 djm Exp $ */ +/* $OpenBSD: ssh.c,v 1.630 2026/04/02 07:50:55 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -43,21 +43,16 @@ #include "includes.h" #include -#ifdef HAVE_SYS_STAT_H -# include -#endif -#include -#include #include +#include #include +#include #include #include #include #include -#ifdef HAVE_PATHS_H #include -#endif #include #include #include @@ -65,7 +60,6 @@ #include #include #include -#include #include #include #include @@ -78,12 +72,10 @@ #include #endif #include "openbsd-compat/openssl-compat.h" -#include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "ssh.h" #include "ssh2.h" -#include "canohost.h" #include "compat.h" #include "cipher.h" #include "packet.h" @@ -93,7 +85,6 @@ #include "authfd.h" #include "authfile.h" #include "pathnames.h" -#include "dispatch.h" #include "clientloop.h" #include "log.h" #include "misc.h" @@ -101,12 +92,9 @@ #include "sshconnect.h" #include "kex.h" #include "mac.h" -#include "sshpty.h" #include "match.h" -#include "msg.h" #include "version.h" #include "ssherr.h" -#include "myproposal.h" #include "utf8.h" #ifdef ENABLE_PKCS11 @@ -528,16 +516,28 @@ resolve_canonicalize(char **hostp, int port) static void check_load(int r, struct sshkey **k, const char *path, const char *message) { + char *fp; + switch (r) { case 0: + if (k == NULL || *k == NULL) + return; /* Check RSA keys size and discard if undersized */ - if (k != NULL && *k != NULL && - (r = sshkey_check_rsa_length(*k, + if ((r = sshkey_check_rsa_length(*k, options.required_rsa_size)) != 0) { error_r(r, "load %s \"%s\"", message, path); free(*k); *k = NULL; + break; } + if ((fp = sshkey_fingerprint(*k, + options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { + fatal_f("failed to fingerprint %s %s key from %s", + sshkey_type(*k), message, path); + } + debug("loaded %s from %s: %s %s", message, path, + sshkey_type(*k), fp); + free(fp); break; case SSH_ERR_INTERNAL_ERROR: case SSH_ERR_ALLOC_FAIL: @@ -551,6 +551,8 @@ check_load(int r, struct sshkey **k, const char *path, const char *message) error_r(r, "load %s \"%s\"", message, path); break; } + if (k != NULL && *k == NULL) + debug("no %s loaded from %s", message, path); } /* @@ -558,15 +560,18 @@ check_load(int r, struct sshkey **k, const char *path, const char *message) * file if the user specifies a config file on the command line. */ static void -process_config_files(const char *host_name, struct passwd *pw, int final_pass, - int *want_final_pass) +process_config_files(const char *host_name, struct passwd *pw, + int final_pass, int *want_final_pass) { - char buf[PATH_MAX]; + char *cmd, buf[PATH_MAX]; int r; + if ((cmd = sshbuf_dup_string(command)) == NULL) + fatal_f("sshbuf_dup_string failed"); if (config != NULL) { if (strcasecmp(config, "none") != 0 && - !read_config_file(config, pw, host, host_name, &options, + !read_config_file(config, pw, host, host_name, cmd, + &options, SSHCONF_USERCONF | (final_pass ? SSHCONF_FINAL : 0), want_final_pass)) fatal("Can't open user config file %.100s: " @@ -575,15 +580,16 @@ process_config_files(const char *host_name, struct passwd *pw, int final_pass, r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) - (void)read_config_file(buf, pw, host, host_name, + (void)read_config_file(buf, pw, host, host_name, cmd, &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | (final_pass ? SSHCONF_FINAL : 0), want_final_pass); /* Read systemwide configuration file after user config. */ (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, - host, host_name, &options, + host, host_name, cmd, &options, final_pass ? SSHCONF_FINAL : 0, want_final_pass); } + free(cmd); } /* Rewrite the port number in an addrinfo list of addresses */ @@ -626,41 +632,6 @@ ssh_conn_info_free(struct ssh_conn_info *cinfo) free(cinfo); } -static int -valid_hostname(const char *s) -{ - size_t i; - - if (*s == '-') - return 0; - for (i = 0; s[i] != 0; i++) { - if (strchr("'`\"$\\;&<>|(){}", s[i]) != NULL || - isspace((u_char)s[i]) || iscntrl((u_char)s[i])) - return 0; - } - return 1; -} - -static int -valid_ruser(const char *s) -{ - size_t i; - - if (*s == '-') - return 0; - for (i = 0; s[i] != 0; i++) { - if (strchr("'`\";&<>|(){}", s[i]) != NULL) - return 0; - /* Disallow '-' after whitespace */ - if (isspace((u_char)s[i]) && s[i + 1] == '-') - return 0; - /* Disallow \ in last position */ - if (s[i] == '\\' && s[i + 1] == '\0') - return 0; - } - return 1; -} - /* * Main program for the ssh client. */ @@ -670,7 +641,8 @@ main(int ac, char **av) struct ssh *ssh = NULL; int i, r, opt, exit_status, use_syslog, direct, timeout_ms; int was_addr, config_test = 0, opt_terminated = 0, want_final_pass = 0; - char *p, *cp, *line, *argv0, *logfile; + int user_on_commandline = 0, user_was_default = 0, user_expanded = 0; + char *p, *cp, *line, *argv0, *logfile, *args; char cname[NI_MAXHOST], thishost[NI_MAXHOST]; struct stat st; struct passwd *pw; @@ -680,6 +652,7 @@ main(int ac, char **av) struct addrinfo *addrs = NULL; size_t n, len; u_int j; + struct utsname utsname; struct ssh_conn_info *cinfo = NULL; /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ @@ -739,6 +712,7 @@ main(int ac, char **av) channel_init_channels(ssh); /* Parse command-line arguments. */ + args = argv_assemble(ac, av); /* logged later */ host = NULL; use_syslog = 0; logfile = NULL; @@ -797,6 +771,10 @@ main(int ac, char **av) fatal("Multiplexing command already specified"); if (strcmp(optarg, "check") == 0) muxclient_command = SSHMUX_COMMAND_ALIVE_CHECK; + else if (strcmp(optarg, "conninfo") == 0) + muxclient_command = SSHMUX_COMMAND_CONNINFO; + else if (strcmp(optarg, "channels") == 0) + muxclient_command = SSHMUX_COMMAND_CHANINFO; else if (strcmp(optarg, "forward") == 0) muxclient_command = SSHMUX_COMMAND_FORWARD; else if (strcmp(optarg, "exit") == 0) @@ -905,9 +883,9 @@ main(int ac, char **av) } if (options.proxy_command != NULL) fatal("Cannot specify -J with ProxyCommand"); - if (parse_jump(optarg, &options, 1) == -1) + if (parse_jump(optarg, &options, 1, 1) == -1) + fatal("Invalid -J argument"); - options.proxy_command = xstrdup("none"); break; case 't': if (options.request_tty == REQUEST_TTY_YES) @@ -965,7 +943,7 @@ main(int ac, char **av) options.log_level = SYSLOG_LEVEL_QUIET; break; case 'e': - if (optarg[0] == '^' && optarg[2] == 0 && + if (strlen(optarg) == 2 && optarg[0] == '^' && (u_char) optarg[1] >= 64 && (u_char) optarg[1] < 128) options.escape_char = (u_char) optarg[1] & 31; @@ -1016,8 +994,10 @@ main(int ac, char **av) } break; case 'l': - if (options.user == NULL) - options.user = optarg; + if (options.user == NULL) { + options.user = xstrdup(optarg); + user_on_commandline = 1; + } break; case 'L': @@ -1074,7 +1054,7 @@ main(int ac, char **av) case 'o': line = xstrdup(optarg); if (process_config_line(&options, pw, - host ? host : "", host ? host : "", line, + host ? host : "", host ? host : "", "", line, "command-line", 0, NULL, SSHCONF_USERCONF) != 0) exit(255); free(line); @@ -1120,6 +1100,7 @@ main(int ac, char **av) if (options.user == NULL) { options.user = tuser; tuser = NULL; + user_on_commandline = 1; } free(tuser); if (options.port == -1 && tport != -1) @@ -1134,6 +1115,7 @@ main(int ac, char **av) if (options.user == NULL) { options.user = p; p = NULL; + user_on_commandline = 1; } *cp++ = '\0'; host = xstrdup(cp); @@ -1153,10 +1135,15 @@ main(int ac, char **av) if (!host) usage(); - if (!valid_hostname(host)) - fatal("hostname contains invalid characters"); - if (options.user != NULL && !valid_ruser(options.user)) + /* + * Validate commandline-specified values that end up in %tokens + * before they are used in config parsing. + */ + if (options.user != NULL && !ssh_valid_ruser(options.user)) fatal("remote username contains invalid characters"); + if (!ssh_valid_hostname(host)) + fatal("hostname contains invalid characters"); + options.host_arg = xstrdup(host); /* Initialize the command to execute on remote host. */ @@ -1201,8 +1188,15 @@ main(int ac, char **av) SYSLOG_FACILITY_USER : options.log_facility, !use_syslog); - if (debug_flag) - logit("%s, %s", SSH_RELEASE, SSH_OPENSSL_VERSION); + debug("%s, %s", SSH_RELEASE, SSH_OPENSSL_VERSION); + if (uname(&utsname) != 0) { + memset(&utsname, 0, sizeof(utsname)); + strlcpy(utsname.sysname, "UNKNOWN", sizeof(utsname.sysname)); + } + debug3("Running on %s %s %s %s", utsname.sysname, utsname.release, + utsname.version, utsname.machine); + debug3("Started with: %s", args); + free(args); /* Parse the configuration files */ process_config_files(options.host_arg, pw, 0, &want_final_pass); @@ -1288,8 +1282,10 @@ main(int ac, char **av) if (fill_default_options(&options) != 0) cleanup_exit(255); - if (options.user == NULL) + if (options.user == NULL) { + user_was_default = 1; options.user = xstrdup(pw->pw_name); + } /* * If ProxyJump option specified, then construct a ProxyCommand now. @@ -1317,7 +1313,8 @@ main(int ac, char **av) sshbin = "ssh"; /* Consistency check */ - if (options.proxy_command != NULL) + if (options.proxy_command != NULL && + strcasecmp(options.proxy_command, "none") != 0) fatal("inconsistent options: ProxyCommand+ProxyJump"); /* Never use FD passing for ProxyJump */ options.proxy_use_fdpass = 0; @@ -1349,6 +1346,8 @@ main(int ac, char **av) if (options.port == 0) options.port = default_ssh_port(); channel_set_af(ssh, options.address_family); + ssh_packet_set_qos(ssh, options.ip_qos_interactive, + options.ip_qos_bulk); /* Tidy and check options */ if (options.host_key_alias != NULL) @@ -1430,11 +1429,38 @@ main(int ac, char **av) options.host_key_alias : options.host_arg); cinfo->host_arg = xstrdup(options.host_arg); cinfo->remhost = xstrdup(host); - cinfo->remuser = xstrdup(options.user); cinfo->homedir = xstrdup(pw->pw_dir); cinfo->locuser = xstrdup(pw->pw_name); cinfo->jmphost = xstrdup(options.jump_host == NULL ? "" : options.jump_host); + + /* + * If the user was specified via a configuration directive then attempt + * to expand it. It cannot contain %r (itself) or %C since User is + * a component of the hash. + */ + if (!user_on_commandline && !user_was_default) { + if ((p = percent_dollar_expand(options.user, + DEFAULT_CLIENT_PERCENT_EXPAND_ARGS_NOUSER(cinfo), + (char *)NULL)) == NULL) + fatal("invalid environment variable expansion"); + user_expanded = strcmp(p, options.user) != 0; + free(options.user); + options.user = p; + } + + /* + * Usernames specified on the commandline or expanded from the + * configuration file must be validated. + * Conversely, usernames from getpwnam(3) or specified as literals + * via configuration (i.e. not expanded) are not subject to validation. + */ + if ((user_on_commandline || user_expanded) && + !ssh_valid_ruser(options.user)) + fatal("remote username contains invalid characters"); + + /* Now User is expanded, store it and calculate hash. */ + cinfo->remuser = xstrdup(options.user); cinfo->conn_hash_hex = ssh_connection_hash(cinfo->thishost, cinfo->remhost, cinfo->portstr, cinfo->remuser, cinfo->jmphost); @@ -1471,12 +1497,13 @@ main(int ac, char **av) options.identity_agent = cp; } - if (options.revoked_host_keys != NULL) { - p = tilde_expand_filename(options.revoked_host_keys, getuid()); + for (j = 0; j < options.num_revoked_host_keys; j++) { + p = tilde_expand_filename(options.revoked_host_keys[j], + getuid()); cp = default_client_percent_dollar_expand(p, cinfo); free(p); - free(options.revoked_host_keys); - options.revoked_host_keys = cp; + free(options.revoked_host_keys[j]); + options.revoked_host_keys[j] = cp; } if (options.forward_agent_sock_path != NULL) { @@ -1494,6 +1521,13 @@ main(int ac, char **av) } } + if (options.version_addendum != NULL) { + cp = default_client_percent_dollar_expand( + options.version_addendum, cinfo); + free(options.version_addendum); + options.version_addendum = cp; + } + if (options.num_system_hostfiles > 0 && strcasecmp(options.system_hostfiles[0], "none") == 0) { if (options.num_system_hostfiles > 1) @@ -1526,6 +1560,28 @@ main(int ac, char **av) options.user_hostfiles[j] = p; } + for (j = 0; j < options.num_setenv; j++) { + char *name = options.setenv[j], *value; + + if (name == NULL) + continue; + /* Expand only the value portion, not the variable name. */ + if ((value = strchr(name, '=')) == NULL) { + /* shouldn't happen; vars are checked in readconf.c */ + fatal("Invalid config SetEnv: %s", name); + } + *value++ = '\0'; + cp = default_client_percent_dollar_expand(value, cinfo); + xasprintf(&p, "%s=%s", name, cp); + if (strcmp(value, p) != 0) { + debug3("expanded SetEnv '%s' '%s' -> '%s'", + name, value, cp); + } + free(options.setenv[j]); + free(cp); + options.setenv[j] = p; + } + for (i = 0; i < options.num_local_forwards; i++) { if (options.local_forwards[i].listen_path != NULL) { cp = options.local_forwards[i].listen_path; @@ -1636,8 +1692,6 @@ main(int ac, char **av) &timeout_ms, options.tcp_keep_alive) != 0) exit(255); - if (addrs != NULL) - freeaddrinfo(addrs); ssh_packet_set_timeout(ssh, options.server_alive_interval, options.server_alive_count_max); @@ -1664,10 +1718,9 @@ main(int ac, char **av) if ((o) >= sensitive_data.nkeys) \ fatal_f("pubkey out of array bounds"); \ check_load(sshkey_load_public(p, &(sensitive_data.keys[o]), NULL), \ - &(sensitive_data.keys[o]), p, "pubkey"); \ + &(sensitive_data.keys[o]), p, "hostbased pubkey"); \ if (sensitive_data.keys[o] != NULL) { \ - debug2("hostbased key %d: %s key from \"%s\"", o, \ - sshkey_ssh_name(sensitive_data.keys[o]), p); \ + debug2("hostbased pubkey \"%s\" in slot %d", p, o); \ loaded++; \ } \ } while (0) @@ -1675,10 +1728,9 @@ main(int ac, char **av) if ((o) >= sensitive_data.nkeys) \ fatal_f("cert out of array bounds"); \ check_load(sshkey_load_cert(p, &(sensitive_data.keys[o])), \ - &(sensitive_data.keys[o]), p, "cert"); \ + &(sensitive_data.keys[o]), p, "hostbased cert"); \ if (sensitive_data.keys[o] != NULL) { \ - debug2("hostbased key %d: %s cert from \"%s\"", o, \ - sshkey_ssh_name(sensitive_data.keys[o]), p); \ + debug2("hostbased cert \"%s\" in slot %d", p, o); \ loaded++; \ } \ } while (0) @@ -1687,17 +1739,9 @@ main(int ac, char **av) L_CERT(_PATH_HOST_ECDSA_KEY_FILE, 0); L_CERT(_PATH_HOST_ED25519_KEY_FILE, 1); L_CERT(_PATH_HOST_RSA_KEY_FILE, 2); -#ifdef WITH_DSA - L_CERT(_PATH_HOST_DSA_KEY_FILE, 3); -#endif L_PUBKEY(_PATH_HOST_ECDSA_KEY_FILE, 4); L_PUBKEY(_PATH_HOST_ED25519_KEY_FILE, 5); L_PUBKEY(_PATH_HOST_RSA_KEY_FILE, 6); -#ifdef WITH_DSA - L_PUBKEY(_PATH_HOST_DSA_KEY_FILE, 7); -#endif - L_CERT(_PATH_HOST_XMSS_KEY_FILE, 8); - L_PUBKEY(_PATH_HOST_XMSS_KEY_FILE, 9); if (loaded == 0) debug("HostbasedAuthentication enabled but no " "local public host keys could be loaded."); @@ -1788,9 +1832,13 @@ main(int ac, char **av) #endif skip_connect: + if (addrs != NULL) + freeaddrinfo(addrs); exit_status = ssh_session2(ssh, cinfo); ssh_conn_info_free(cinfo); - ssh_packet_close(ssh); + channel_free_channels(ssh); + ssh_packet_free(ssh); + pwfree(pw); if (options.control_path != NULL && muxserver_sock != -1) unlink(options.control_path); @@ -1873,7 +1921,7 @@ forwarding_success(void) /* Callback for remote forward global requests */ static void -ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt) +ssh_confirm_remote_forward(struct ssh *ssh, int type, uint32_t seq, void *ctxt) { struct Forward *rfwd = (struct Forward *)ctxt; u_int port; @@ -2117,7 +2165,6 @@ ssh_session2_setup(struct ssh *ssh, int id, int success, void *arg) { extern char **environ; const char *display, *term; - int r, interactive = tty_flag; char *proto = NULL, *data = NULL; if (!success) @@ -2136,20 +2183,11 @@ ssh_session2_setup(struct ssh *ssh, int id, int success, void *arg) data, 1); client_expect_confirm(ssh, id, "X11 forwarding", CONFIRM_WARN); /* XXX exit_on_forward_failure */ - interactive = 1; } check_agent_present(); - if (options.forward_agent) { - debug("Requesting authentication agent forwarding."); - channel_request_start(ssh, id, "auth-agent-req@openssh.com", 0); - if ((r = sshpkt_send(ssh)) != 0) - fatal_fr(r, "send packet"); - } - - /* Tell the packet module whether this is an interactive session. */ - ssh_packet_set_interactive(ssh, interactive, - options.ip_qos_interactive, options.ip_qos_bulk); + if (options.forward_agent) + client_channel_reqest_agent_forwarding(ssh, id); if ((term = lookup_env_in_list("TERM", options.setenv, options.num_setenv)) == NULL || *term == '\0') @@ -2187,8 +2225,9 @@ ssh_session2_open(struct ssh *ssh) "session", SSH_CHANNEL_OPENING, in, out, err, window, packetmax, CHAN_EXTENDED_WRITE, "client-session", CHANNEL_NONBLOCK_STDIO); - - debug3_f("channel_new: %d", c->self); + if (tty_flag) + channel_set_tty(ssh, c); + debug3_f("channel_new: %d%s", c->self, tty_flag ? " (tty)" : ""); channel_send_open(ssh, c->self); if (options.session_type != SESSION_TYPE_NONE) @@ -2201,7 +2240,7 @@ ssh_session2_open(struct ssh *ssh) static int ssh_session2(struct ssh *ssh, const struct ssh_conn_info *cinfo) { - int r, interactive, id = -1; + int r, id = -1; char *cp, *tun_fwd_ifname = NULL; /* XXX should be pre-session */ @@ -2257,14 +2296,6 @@ ssh_session2(struct ssh *ssh, const struct ssh_conn_info *cinfo) if (options.session_type != SESSION_TYPE_NONE) id = ssh_session2_open(ssh); - else { - interactive = options.control_master == SSHCTL_MASTER_NO; - /* ControlPersist may have clobbered ControlMaster, so check */ - if (need_controlpersist_detach) - interactive = otty_flag != 0; - ssh_packet_set_interactive(ssh, interactive, - options.ip_qos_interactive, options.ip_qos_bulk); - } /* If we don't expect to open a new session, then disallow it */ if (options.control_master == SSHCTL_MASTER_NO && @@ -2389,9 +2420,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) continue; xasprintf(&cp, "%s-cert", filename); check_load(sshkey_load_public(cp, &public, NULL), - &public, filename, "pubkey"); - debug("identity file %s type %d", cp, - public ? public->type : -1); + &public, filename, "identity pubkey"); if (public == NULL) { free(cp); continue; @@ -2403,6 +2432,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) free(cp); continue; } + free(cp); /* NB. leave filename pointing to private key */ identity_files[n_ids] = xstrdup(filename); identity_keys[n_ids] = public; @@ -2420,9 +2450,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) free(cp); check_load(sshkey_load_public(filename, &public, NULL), - &public, filename, "certificate"); - debug("certificate file %s type %d", filename, - public ? public->type : -1); + &public, filename, "identity cert"); free(options.certificate_files[i]); options.certificate_files[i] = NULL; if (public == NULL) { diff --git a/ssh.h b/ssh.h index 8110c06..cd95dd8 100644 --- a/ssh.h +++ b/ssh.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.h,v 1.90 2020/07/14 23:57:01 djm Exp $ */ +/* $OpenBSD: ssh.h,v 1.91 2024/09/25 23:01:39 jsg Exp $ */ /* * Author: Tatu Ylonen @@ -12,9 +12,6 @@ * called by a name other than "ssh" or "Secure Shell". */ -/* Cipher used for encrypting authentication files. */ -#define SSH_AUTHFILE_CIPHER SSH_CIPHER_3DES - /* Default port number. */ #define SSH_DEFAULT_PORT 22 @@ -36,11 +33,9 @@ * * Minor protocol version. Different version indicates minor incompatibility * that does not prevent interoperation. + * + * We support only SSH2 */ -#define PROTOCOL_MAJOR_1 1 -#define PROTOCOL_MINOR_1 5 - -/* We support only SSH2 */ #define PROTOCOL_MAJOR_2 2 #define PROTOCOL_MINOR_2 0 @@ -72,12 +67,6 @@ */ #define SSH_ASKPASS_REQUIRE_ENV "SSH_ASKPASS_REQUIRE" -/* - * Force host key length and server key length to differ by at least this - * many bits. This is to make double encryption with rsaref work. - */ -#define SSH_KEY_BITS_RESERVED 128 - /* * Length of the session key in bytes. (Specified as 256 bits in the * protocol.) diff --git a/ssh_api.c b/ssh_api.c index 5faaffd..38ac17d 100644 --- a/ssh_api.c +++ b/ssh_api.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh_api.c,v 1.31 2024/09/09 02:39:57 djm Exp $ */ +/* $OpenBSD: ssh_api.c,v 1.34 2026/03/03 09:57:25 dtucker Exp $ */ /* * Copyright (c) 2012 Markus Friedl. All rights reserved. * @@ -255,7 +255,7 @@ int ssh_packet_next(struct ssh *ssh, u_char *typep) { int r; - u_int32_t seqnr; + uint32_t seqnr; u_char type; /* @@ -532,7 +532,7 @@ _ssh_order_hostkeyalgs(struct ssh *ssh) char *orig, *avail, *oavail = NULL, *alg, *replace = NULL; char **proposal; size_t maxlen; - int ktype, r; + int ktype, nid, r; /* XXX we de-serialize ssh->kex->my, modify it, and change it */ if ((r = kex_buf2prop(ssh->kex->my, NULL, &proposal)) != 0) @@ -551,15 +551,20 @@ _ssh_order_hostkeyalgs(struct ssh *ssh) while ((alg = strsep(&avail, ",")) && *alg != '\0') { if ((ktype = sshkey_type_from_name(alg)) == KEY_UNSPEC) continue; + nid = sshkey_ecdsa_nid_from_name(alg); TAILQ_FOREACH(k, &ssh->public_keys, next) { - if (k->key->type == ktype || - (sshkey_is_cert(k->key) && k->key->type == - sshkey_type_plain(ktype))) { - if (*replace != '\0') - strlcat(replace, ",", maxlen); - strlcat(replace, alg, maxlen); - break; - } + if (k->key->type != ktype && + (!sshkey_is_cert(k->key) || + k->key->type != sshkey_type_plain(ktype))) + continue; + if (sshkey_type_plain(k->key->type) == KEY_ECDSA && + k->key->ecdsa_nid != nid) + continue; + /* Candidate */ + if (*replace != '\0') + strlcat(replace, ",", maxlen); + strlcat(replace, alg, maxlen); + break; } } if (*replace != '\0') { diff --git a/ssh_api.h b/ssh_api.h index 584f896..d5ba574 100644 --- a/ssh_api.h +++ b/ssh_api.h @@ -18,11 +18,10 @@ #ifndef API_H #define API_H +#include #include #include -#include "openbsd-compat/sys-queue.h" - #include "cipher.h" #include "sshkey.h" #include "kex.h" diff --git a/ssh_config b/ssh_config index cc56635..238a0c5 100644 --- a/ssh_config +++ b/ssh_config @@ -1,4 +1,4 @@ -# $OpenBSD: ssh_config,v 1.36 2023/08/02 23:04:38 djm Exp $ +# $OpenBSD: ssh_config,v 1.37 2025/05/06 05:40:56 djm Exp $ # This is the ssh client system-wide configuration file. See # ssh_config(5) for more information. This file provides defaults for @@ -30,7 +30,6 @@ # ConnectTimeout 0 # StrictHostKeyChecking ask # IdentityFile ~/.ssh/id_rsa -# IdentityFile ~/.ssh/id_dsa # IdentityFile ~/.ssh/id_ecdsa # IdentityFile ~/.ssh/id_ed25519 # Port 22 diff --git a/ssh_config.0 b/ssh_config.0 index dd37bff..1c9273f 100644 --- a/ssh_config.0 +++ b/ssh_config.0 @@ -55,11 +55,11 @@ DESCRIPTION Match keyword are satisfied. Match conditions are specified using one or more criteria or the single token all which always matches. The available criteria keywords are: canonical, final, - exec, localnetwork, host, originalhost, tagged, user, and - localuser. The all criteria must appear alone or immediately - after canonical or final. Other criteria may be combined - arbitrarily. All criteria but all, canonical, and final require - an argument. Criteria may be negated by prepending an + exec, localnetwork, host, originalhost, tagged, command, user, + localuser, and version. The all criteria must appear alone or + immediately after canonical or final. Other criteria may be + combined arbitrarily. All criteria but all, canonical, and final + require an argument. Criteria may be negated by prepending an exclamation mark (M-bM-^@M-^X!M-bM-^@M-^Y). The canonical keyword matches only when the configuration file is @@ -89,16 +89,32 @@ DESCRIPTION The other keywords' criteria must be single entries or comma- separated lists and may use the wildcard and negation operators - described in the PATTERNS section. The criteria for the host - keyword are matched against the target hostname, after any - substitution by the Hostname or CanonicalizeHostname options. - The originalhost keyword matches against the hostname as it was - specified on the command-line. The tagged keyword matches a tag - name specified by a prior Tag directive or on the ssh(1) command- - line using the -P flag. The user keyword matches against the - target username on the remote host. The localuser keyword - matches against the name of the local user running ssh(1) (this - keyword may be useful in system-wide ssh_config files). + described in the PATTERNS section. + + The criteria for the host keyword are matched against the target + hostname, after any substitution by the Hostname or + CanonicalizeHostname options. The originalhost keyword matches + against the hostname as it was specified on the command-line. + + The tagged keyword matches a tag name specified by a prior Tag + directive or on the ssh(1) command-line using the -P flag. The + command keyword matches the remote command that has been + requested, or the subsystem name that is being invoked (e.g. + "sftp" for an SFTP session). The empty string will match the + case where a command or tag has not been specified, i.e. M-bM-^@M-^XMatch + tag ""M-bM-^@M-^Y. The version keyword matches against the version string + of ssh(1), for example M-bM-^@M-^\OpenSSH_10.0M-bM-^@M-^]. + + The user keyword matches against the target username on the + remote host. The localuser keyword matches against the name of + the local user running ssh(1) (this keyword may be useful in + system-wide ssh_config files). + + Finally, the sessiontype keyword matches the requested session + type, which may be one of shell for interactive sessions, exec + for command execution sessions, subsystem for subsystem + invocations such as sftp(1), or none for transport-only sessions, + such as when ssh(1) is started with the -N flag. AddKeysToAgent Specifies whether keys should be automatically added to a running @@ -250,13 +266,13 @@ DESCRIPTION direct-tcpip, direct-streamlocal@openssh.com Open TCP or Unix socket (respectively) connections that - have been established from a ssh(1) local forwarding, + have been established from an ssh(1) local forwarding, i.e. LocalForward or DynamicForward. forwarded-tcpip, forwarded-streamlocal@openssh.com Open TCP or Unix socket (respectively) connections that - have been established to a sshd(8) listening on behalf of - a ssh(1) remote forwarding, i.e. RemoteForward. + have been established to an sshd(8) listening on behalf + of an ssh(1) remote forwarding, i.e. RemoteForward. session The interactive main session, including shell session, @@ -317,8 +333,8 @@ DESCRIPTION The default is: chacha20-poly1305@openssh.com, - aes128-ctr,aes192-ctr,aes256-ctr, - aes128-gcm@openssh.com,aes256-gcm@openssh.com + aes128-gcm@openssh.com,aes256-gcm@openssh.com, + aes128-ctr,aes192-ctr,aes256-ctr The list of available ciphers may also be obtained using "ssh -Q cipher". @@ -570,12 +586,14 @@ DESCRIPTION ecdsa-sha2-nistp521-cert-v01@openssh.com, sk-ssh-ed25519-cert-v01@openssh.com, sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, + webauthn-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, rsa-sha2-512-cert-v01@openssh.com, rsa-sha2-256-cert-v01@openssh.com, ssh-ed25519, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, sk-ssh-ed25519@openssh.com, sk-ecdsa-sha2-nistp256@openssh.com, + webauthn-sk-ecdsa-sha2-nistp256@openssh.com, rsa-sha2-512,rsa-sha2-256 The -Q option of ssh(1) may be used to list supported signature @@ -604,11 +622,13 @@ DESCRIPTION ecdsa-sha2-nistp521-cert-v01@openssh.com, sk-ssh-ed25519-cert-v01@openssh.com, sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, + webauthn-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, rsa-sha2-512-cert-v01@openssh.com, rsa-sha2-256-cert-v01@openssh.com, ssh-ed25519, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, sk-ecdsa-sha2-nistp256@openssh.com, + webauthn-sk-ecdsa-sha2-nistp256@openssh.com sk-ssh-ed25519@openssh.com, rsa-sha2-512,rsa-sha2-256 @@ -644,7 +664,7 @@ DESCRIPTION many different identities. IdentityAgent - Specifies the UNIX-domain socket used to communicate with the + Specifies the Unix-domain socket used to communicate with the authentication agent. This option overrides the SSH_AUTH_SOCK environment variable and @@ -713,18 +733,18 @@ DESCRIPTION from the system configuration file. Include directive may appear inside a Match or Host block to perform conditional inclusion. - IPQoS Specifies the IPv4 type-of-service or DSCP class for connections. - Accepted values are af11, af12, af13, af21, af22, af23, af31, - af32, af33, af41, af42, af43, cs0, cs1, cs2, cs3, cs4, cs5, cs6, - cs7, ef, le, lowdelay, throughput, reliability, a numeric value, - or none to use the operating system default. This option may - take one or two arguments, separated by whitespace. If one - argument is specified, it is used as the packet class - unconditionally. If two values are specified, the first is - automatically selected for interactive sessions and the second - for non-interactive sessions. The default is af21 (Low-Latency - Data) for interactive sessions and cs1 (Lower Effort) for non- - interactive sessions. + IPQoS Specifies the Differentiated Services Field Codepoint (DSCP) + value for connections. Accepted values are af11, af12, af13, + af21, af22, af23, af31, af32, af33, af41, af42, af43, cs0, cs1, + cs2, cs3, cs4, cs5, cs6, cs7, ef, le, a numeric value, or none to + use the operating system default. This option may take one or + two arguments, separated by whitespace. If one argument is + specified, it is used as the packet class unconditionally. If + two values are specified, the first is automatically selected for + interactive sessions and the second for non-interactive sessions. + The default is ef (Expedited Forwarding) for interactive sessions + and none (the operating system default) for non-interactive + sessions. KbdInteractiveAuthentication Specifies whether to use keyboard-interactive authentication. @@ -755,8 +775,8 @@ DESCRIPTION The default is: - sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com, mlkem768x25519-sha256, + sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com, curve25519-sha256,curve25519-sha256@libssh.org, ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, diffie-hellman-group-exchange-sha256, @@ -798,21 +818,28 @@ DESCRIPTION enabled. LocalForward - Specifies that a TCP port on the local machine be forwarded over - the secure channel to the specified host and port from the remote - machine. The first argument specifies the listener and may be - [bind_address:]port or a Unix domain socket path. The second - argument is the destination and may be host:hostport or a Unix - domain socket path if the remote host supports it. + Specifies that a TCP port or Unix-domain socket on the local + machine be forwarded over the secure channel to the specified + host and port (or Unix-domain socket) from the remote machine. + For a TCP port, the first argument must be [bind_address:]port or + a Unix domain socket path. The second argument is the + destination and may be host:hostport or a Unix domain socket path + if the remote host supports it. IPv6 addresses can be specified by enclosing addresses in square - brackets. Multiple forwardings may be specified, and additional - forwardings can be given on the command line. Only the superuser - can forward privileged ports. By default, the local port is - bound in accordance with the GatewayPorts setting. However, an - explicit bind_address may be used to bind the connection to a - specific address. The bind_address of localhost indicates that - the listening port be bound for local use only, while an empty + brackets. + + If either argument contains a '/' in it, that argument will be + interpreted as a Unix-domain socket (on the corresponding host) + rather than a TCP port. + + Multiple forwardings may be specified, and additional forwardings + can be given on the command line. Only the superuser can forward + privileged ports. By default, the local port is bound in + accordance with the GatewayPorts setting. However, an explicit + bind_address may be used to bind the connection to a specific + address. The bind_address of localhost indicates that the + listening port be bound for local use only, while an empty address or M-bM-^@M-^X*M-bM-^@M-^Y indicates that the port should be available from all interfaces. Unix domain socket paths may use the tokens described in the TOKENS section and environment variables as @@ -956,8 +983,8 @@ DESCRIPTION Specifies one or more jump proxies as either [user@]host[:port] or an ssh URI. Multiple proxies may be separated by comma characters and will be visited sequentially. Setting this option - will cause ssh(1) to connect to the target host by first making a - ssh(1) connection to the specified ProxyJump host and then + will cause ssh(1) to connect to the target host by first making + an ssh(1) connection to the specified ProxyJump host and then establishing a TCP forwarding to the ultimate target from there. Setting the host to none disables this option entirely. @@ -993,12 +1020,14 @@ DESCRIPTION ecdsa-sha2-nistp521-cert-v01@openssh.com, sk-ssh-ed25519-cert-v01@openssh.com, sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, + webauthn-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, rsa-sha2-512-cert-v01@openssh.com, rsa-sha2-256-cert-v01@openssh.com, ssh-ed25519, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, sk-ssh-ed25519@openssh.com, sk-ecdsa-sha2-nistp256@openssh.com, + webauthn-sk-ecdsa-sha2-nistp256@openssh.com, rsa-sha2-512,rsa-sha2-256 The list of available signature algorithms may also be obtained @@ -1012,6 +1041,14 @@ DESCRIPTION OpenSSH host-bound authentication protocol extension required for restricted ssh-agent(1) forwarding. + RefuseConnection + Allows a connection to be refused by the configuration file. If + this option is specified, then ssh(1) will terminate immediately + before attempting to connect to the remote host, display an error + message that contains the argument to this keyword and return a + non-zero exit status. This option may be useful to express + reminders or warnings to the user via ssh_config. + RekeyLimit Specifies the maximum amount of data that may be transmitted or received before the session key is renegotiated, optionally @@ -1034,27 +1071,34 @@ DESCRIPTION the TOKENS section. RemoteForward - Specifies that a TCP port on the remote machine be forwarded over - the secure channel. The remote port may either be forwarded to a - specified host and port from the local machine, or may act as a - SOCKS 4/5 proxy that allows a remote client to connect to - arbitrary destinations from the local machine. The first - argument is the listening specification and may be - [bind_address:]port or, if the remote host supports it, a Unix - domain socket path. If forwarding to a specific destination then - the second argument must be host:hostport or a Unix domain socket - path, otherwise if no destination argument is specified then the - remote forwarding will be established as a SOCKS proxy. When - acting as a SOCKS proxy, the destination of the connection can be - restricted by PermitRemoteOpen. + Specifies that a TCP port or Unix-domain socket on the remote + machine be forwarded over the secure channel. The remote port + may either be forwarded to a specified host and port or Unix- + domain socket from the local machine, or may act as a SOCKS 4/5 + proxy that allows a remote client to connect to arbitrary + destinations from the local machine. The first argument is the + listening specification and may be [bind_address:]port or, if the + remote host supports it, a Unix domain socket path. If + forwarding to a specific destination then the second argument + must be host:hostport or a Unix domain socket path, otherwise if + no destination argument is specified then the remote forwarding + will be established as a SOCKS proxy. When acting as a SOCKS + proxy, the destination of the connection can be restricted by + PermitRemoteOpen. IPv6 addresses can be specified by enclosing addresses in square - brackets. Multiple forwardings may be specified, and additional - forwardings can be given on the command line. Privileged ports - can be forwarded only when logging in as root on the remote - machine. Unix domain socket paths may use the tokens described - in the TOKENS section and environment variables as described in - the ENVIRONMENT VARIABLES section. + brackets. + + If either argument contains a '/' in it, that argument will be + interpreted as a Unix-domain socket (on the corresponding host) + rather than a TCP port. + + Multiple forwardings may be specified, and additional forwardings + can be given on the command line. Privileged ports can be + forwarded only when logging in as root on the remote machine. + Unix domain socket paths may use the tokens described in the + TOKENS section and environment variables as described in the + ENVIRONMENT VARIABLES section. If the port argument is 0, the listen port will be dynamically allocated on the server and reported to the client at run time. @@ -1154,9 +1198,13 @@ DESCRIPTION execution). SetEnv Directly specify one or more environment variables and their - contents to be sent to the server. Similarly to SendEnv, with - the exception of the TERM variable, the server must be prepared - to accept the environment variable. + contents to be sent to the server in the form M-bM-^@M-^\NAME=VALUEM-bM-^@M-^]. + Similarly to SendEnv, with the exception of the TERM variable, + the server must be prepared to accept the environment variable. + + The M-bM-^@M-^\VALUEM-bM-^@M-^] may use the tokens described in the TOKENS section + and environment variables as described in the ENVIRONMENT + VARIABLES section. StdinNull Redirects stdin from /dev/null (actually, prevents reading from @@ -1275,7 +1323,10 @@ DESCRIPTION User Specifies the user to log in as. This can be useful when a different user name is used on different machines. This saves the trouble of having to remember to give the user name on the - command line. + command line. Arguments to User may use the tokens described in + the TOKENS section (with the exception of %r and %C) and + environment variables as described in the ENVIRONMENT VARIABLES + section. UserKnownHostsFile Specifies one or more files to use for the user host key @@ -1298,6 +1349,11 @@ DESCRIPTION See also VERIFYING HOST KEYS in ssh(1). + VersionAddendum + Optionally specifies additional text to append to the SSH + protocol banner sent by the client upon connection. The default + is none. + VisualHostKey If this flag is set to yes, an ASCII art representation of the remote host key fingerprint is printed in addition to the @@ -1306,6 +1362,15 @@ DESCRIPTION printed at login and only the fingerprint string will be printed for unknown host keys. + WarnWeakCrypto + controls whether the user is warned when the cryptographic + algorithms negotiated for the connection are weak or otherwise + recommended against. Warnings may be disabled by turning off a + specific warning or by disabling all warnings. Warnings about + connections that don't use a post-quantum key exchange may be + disabled using the no-pq-kex flag. no will disable all warnings. + The default, equivalent to yes, is to enable all warnings. + XAuthLocation Specifies the full pathname of the xauth(1) program. The default is /usr/X11R6/bin/xauth. @@ -1345,7 +1410,11 @@ PATTERNS TOKENS Arguments to some keywords can make use of tokens, which are expanded at - runtime: + runtime. Tokens are expanded without quoting or escaping of shell + characters. It is the user's responsibility to ensure they are safe in + the context of their use. + + The supported tokens in ssh_config are: %% A literal M-bM-^@M-^X%M-bM-^@M-^Y. %C Hash of %l%h%p%r%j. @@ -1377,8 +1446,8 @@ TOKENS CertificateFile, ControlPath, IdentityAgent, IdentityFile, Include, KnownHostsCommand, LocalForward, Match exec, RemoteCommand, - RemoteForward, RevokedHostKeys, and UserKnownHostsFile accept the tokens - %%, %C, %d, %h, %i, %j, %k, %L, %l, %n, %p, %r, and %u. + RemoteForward, RevokedHostKeys, UserKnownHostsFile and VersionAddendum + accept the tokens %%, %C, %d, %h, %i, %j, %k, %L, %l, %n, %p, %r, and %u. KnownHostsCommand additionally accepts the tokens %f, %H, %I, %K and %t. @@ -1430,4 +1499,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 7.6 September 9, 2024 OpenBSD 7.6 +OpenBSD 7.8 March 23, 2026 SSH_CONFIG(5) diff --git a/ssh_config.5 b/ssh_config.5 index 7c7c5c5..b459b04 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.402 2024/09/09 14:41:21 naddy Exp $ -.Dd $Mdocdate: September 9 2024 $ +.\" $OpenBSD: ssh_config.5,v 1.423 2026/03/23 01:33:46 djm Exp $ +.Dd $Mdocdate: March 23 2026 $ .Dt SSH_CONFIG 5 .Os .Sh NAME @@ -145,9 +145,11 @@ The available criteria keywords are: .Cm host , .Cm originalhost , .Cm tagged , +.Cm command , .Cm user , +.Cm localuser , and -.Cm localuser . +.Cm version . The .Cm all criteria must appear alone or immediately after @@ -212,6 +214,7 @@ The other keywords' criteria must be single entries or comma-separated lists and may use the wildcard and negation operators described in the .Sx PATTERNS section. +.Pp The criteria for the .Cm host keyword are matched against the target hostname, after any substitution @@ -223,6 +226,7 @@ options. The .Cm originalhost keyword matches against the hostname as it was specified on the command-line. +.Pp The .Cm tagged keyword matches a tag name specified by a prior @@ -233,6 +237,22 @@ command-line using the .Fl P flag. The +.Cm command +keyword matches the remote command that has been requested, or the subsystem +name that is being invoked (e.g.\& +.Qq sftp +for an SFTP session). +The empty string will match the case where a command or tag has not been +specified, i.e.\& +.Sq Match tag \&"\&" . +The +.Cm version +keyword matches against the version string of +.Xr ssh 1 , +for example +.Dq OpenSSH_10.0 . +.Pp +The .Cm user keyword matches against the target username on the remote host. The @@ -242,6 +262,24 @@ keyword matches against the name of the local user running (this keyword may be useful in system-wide .Nm files). +.Pp +Finally, the +.Cm sessiontype +keyword matches the requested session type, which may be one of +.Cm shell +for interactive sessions, +.Cm exec +for command execution sessions, +.Cm subsystem +for subsystem invocations such as +.Xr sftp 1 , +or +.Cm none +for transport-only sessions, such as when +.Xr ssh 1 +is started with the +.Fl N +flag. .It Cm AddKeysToAgent Specifies whether keys should be automatically added to a running .Xr ssh-agent 1 . @@ -494,7 +532,7 @@ Open connections to .Xr ssh-agent 1 . .It Cm direct-tcpip , Cm direct-streamlocal@openssh.com Open TCP or Unix socket (respectively) connections that have -been established from a +been established from an .Xr ssh 1 local forwarding, i.e.\& .Cm LocalForward @@ -502,9 +540,9 @@ or .Cm DynamicForward . .It Cm forwarded-tcpip , Cm forwarded-streamlocal@openssh.com Open TCP or Unix socket (respectively) connections that have been -established to a +established to an .Xr sshd 8 -listening on behalf of a +listening on behalf of an .Xr ssh 1 remote forwarding, i.e.\& .Cm RemoteForward . @@ -581,8 +619,8 @@ chacha20-poly1305@openssh.com The default is: .Bd -literal -offset indent chacha20-poly1305@openssh.com, -aes128-ctr,aes192-ctr,aes256-ctr, -aes128-gcm@openssh.com,aes256-gcm@openssh.com +aes128-gcm@openssh.com,aes256-gcm@openssh.com, +aes128-ctr,aes192-ctr,aes256-ctr .Ed .Pp The list of available ciphers may also be obtained using @@ -982,12 +1020,14 @@ ecdsa-sha2-nistp384-cert-v01@openssh.com, ecdsa-sha2-nistp521-cert-v01@openssh.com, sk-ssh-ed25519-cert-v01@openssh.com, sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, +webauthn-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, rsa-sha2-512-cert-v01@openssh.com, rsa-sha2-256-cert-v01@openssh.com, ssh-ed25519, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, sk-ssh-ed25519@openssh.com, sk-ecdsa-sha2-nistp256@openssh.com, +webauthn-sk-ecdsa-sha2-nistp256@openssh.com, rsa-sha2-512,rsa-sha2-256 .Ed .Pp @@ -1028,11 +1068,13 @@ ecdsa-sha2-nistp384-cert-v01@openssh.com, ecdsa-sha2-nistp521-cert-v01@openssh.com, sk-ssh-ed25519-cert-v01@openssh.com, sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, +webauthn-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, rsa-sha2-512-cert-v01@openssh.com, rsa-sha2-256-cert-v01@openssh.com, ssh-ed25519, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, sk-ecdsa-sha2-nistp256@openssh.com, +webauthn-sk-ecdsa-sha2-nistp256@openssh.com sk-ssh-ed25519@openssh.com, rsa-sha2-512,rsa-sha2-256 .Ed @@ -1204,7 +1246,9 @@ or block to perform conditional inclusion. .It Cm IPQoS -Specifies the IPv4 type-of-service or DSCP class for connections. +Specifies the +.Em Differentiated Services Field Codepoint Pq DSCP +value for connections. Accepted values are .Cm af11 , .Cm af12 , @@ -1228,9 +1272,6 @@ Accepted values are .Cm cs7 , .Cm ef , .Cm le , -.Cm lowdelay , -.Cm throughput , -.Cm reliability , a numeric value, or .Cm none to use the operating system default. @@ -1239,11 +1280,11 @@ If one argument is specified, it is used as the packet class unconditionally. If two values are specified, the first is automatically selected for interactive sessions and the second for non-interactive sessions. The default is -.Cm af21 -(Low-Latency Data) +.Cm ef +(Expedited Forwarding) for interactive sessions and -.Cm cs1 -(Lower Effort) +.Cm none +(the operating system default) for non-interactive sessions. .It Cm KbdInteractiveAuthentication Specifies whether to use keyboard-interactive authentication. @@ -1286,8 +1327,8 @@ default set. .Pp The default is: .Bd -literal -offset indent -sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com, mlkem768x25519-sha256, +sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com, curve25519-sha256,curve25519-sha256@libssh.org, ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, diffie-hellman-group-exchange-sha256, @@ -1344,9 +1385,11 @@ This directive is ignored unless .Cm PermitLocalCommand has been enabled. .It Cm LocalForward -Specifies that a TCP port on the local machine be forwarded over -the secure channel to the specified host and port from the remote machine. -The first argument specifies the listener and may be +Specifies that a TCP port or Unix-domain socket on the local machine +be forwarded over +the secure channel to the specified host and port (or Unix-domain socket) +from the remote machine. +For a TCP port, the first argument must be .Sm off .Oo Ar bind_address : Oc Ar port .Sm on @@ -1356,6 +1399,11 @@ The second argument is the destination and may be or a Unix domain socket path if the remote host supports it. .Pp IPv6 addresses can be specified by enclosing addresses in square brackets. +.Pp +If either argument contains a '/' in it, that argument will be +interpreted as a Unix-domain socket (on the corresponding host) rather +than a TCP port. +.Pp Multiple forwardings may be specified, and additional forwardings can be given on the command line. Only the superuser can forward privileged ports. @@ -1584,19 +1632,17 @@ ProxyCommand /usr/bin/nc -X connect -x 192.0.2.0:8080 %h %p .Ed .It Cm ProxyJump Specifies one or more jump proxies as either -.Xo .Sm off .Op Ar user No @ .Ar host .Op : Ns Ar port .Sm on -or an ssh URI -.Xc . +or an ssh URI. Multiple proxies may be separated by comma characters and will be visited sequentially. Setting this option will cause .Xr ssh 1 -to connect to the target host by first making a +to connect to the target host by first making an .Xr ssh 1 connection to the specified .Cm ProxyJump @@ -1647,12 +1693,14 @@ ecdsa-sha2-nistp384-cert-v01@openssh.com, ecdsa-sha2-nistp521-cert-v01@openssh.com, sk-ssh-ed25519-cert-v01@openssh.com, sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, +webauthn-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, rsa-sha2-512-cert-v01@openssh.com, rsa-sha2-256-cert-v01@openssh.com, ssh-ed25519, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, sk-ssh-ed25519@openssh.com, sk-ecdsa-sha2-nistp256@openssh.com, +webauthn-sk-ecdsa-sha2-nistp256@openssh.com, rsa-sha2-512,rsa-sha2-256 .Ed .Pp @@ -1672,6 +1720,15 @@ disabling or enabling the OpenSSH host-bound authentication protocol extension required for restricted .Xr ssh-agent 1 forwarding. +.It Cm RefuseConnection +Allows a connection to be refused by the configuration file. +If this option is specified, then +.Xr ssh 1 +will terminate immediately before attempting to connect to the remote +host, display an error message that contains the argument to this keyword +and return a non-zero exit status. +This option may be useful to express reminders or warnings to the user via +.Nm . .It Cm RekeyLimit Specifies the maximum amount of data that may be transmitted or received before the session key is renegotiated, optionally followed by a maximum @@ -1707,9 +1764,10 @@ accept the tokens described in the .Sx TOKENS section. .It Cm RemoteForward -Specifies that a TCP port on the remote machine be forwarded over -the secure channel. +Specifies that a TCP port or Unix-domain socket on the remote machine +be forwarded over the secure channel. The remote port may either be forwarded to a specified host and port +or Unix-domain socket from the local machine, or may act as a SOCKS 4/5 proxy that allows a remote client to connect to arbitrary destinations from the local machine. The first argument is the listening specification and may be @@ -1727,6 +1785,11 @@ restricted by .Cm PermitRemoteOpen . .Pp IPv6 addresses can be specified by enclosing addresses in square brackets. +.Pp +If either argument contains a '/' in it, that argument will be +interpreted as a Unix-domain socket (on the corresponding host) rather +than a TCP port. +.Pp Multiple forwardings may be specified, and additional forwardings can be given on the command line. Privileged ports can be forwarded only when @@ -1894,12 +1957,21 @@ option) or (shell or command execution). .It Cm SetEnv Directly specify one or more environment variables and their contents to -be sent to the server. +be sent to the server in the form +.Dq NAME=VALUE . Similarly to .Cm SendEnv , with the exception of the .Ev TERM variable, the server must be prepared to accept the environment variable. +.Pp +The +.Dq VALUE +may use the tokens described in the +.Sx TOKENS +section and environment variables as described in the +.Sx ENVIRONMENT VARIABLES +section. .It Cm StdinNull Redirects stdin from .Pa /dev/null @@ -2099,6 +2171,15 @@ Specifies the user to log in as. This can be useful when a different user name is used on different machines. This saves the trouble of having to remember to give the user name on the command line. +Arguments to +.Cm User +may use the tokens described in the +.Sx TOKENS +section +(with the exception of %r and %C) +and environment variables as described in the +.Sx ENVIRONMENT VARIABLES +section. .It Cm UserKnownHostsFile Specifies one or more files to use for the user host key database, separated by whitespace. @@ -2138,6 +2219,11 @@ See also .Sx VERIFYING HOST KEYS in .Xr ssh 1 . +.It Cm VersionAddendum +Optionally specifies additional text to append to the SSH protocol banner +sent by the client upon connection. +The default is +.Cm none . .It Cm VisualHostKey If this flag is set to .Cm yes , @@ -2149,6 +2235,20 @@ If this flag is set to (the default), no fingerprint strings are printed at login and only the fingerprint string will be printed for unknown host keys. +.It Cm WarnWeakCrypto +controls whether the user is warned when the cryptographic algorithms +negotiated for the connection are weak or otherwise recommended against. +Warnings may be disabled by turning off a specific warning or by disabling +all warnings. +Warnings about connections that don't use a post-quantum key exchange +may be disabled using the +.Cm no-pq-kex +flag. +.Cm no +will disable all warnings. +The default, equivalent to +.Cm yes , +is to enable all warnings. .It Cm XAuthLocation Specifies the full pathname of the .Xr xauth 1 @@ -2205,7 +2305,14 @@ such as a wildcard: .Dl from=\&"!host1,!host2,*\&" .Sh TOKENS Arguments to some keywords can make use of tokens, -which are expanded at runtime: +which are expanded at runtime. +Tokens are expanded without quoting or escaping of shell characters. +It is the user's responsibility to ensure they are safe in the +context of their use. +.Pp +The supported tokens in +.Nm +are: .Pp .Bl -tag -width XXXX -offset indent -compact .It %% @@ -2283,8 +2390,9 @@ The local username. .Cm RemoteCommand , .Cm RemoteForward , .Cm RevokedHostKeys , -and .Cm UserKnownHostsFile +and +.Cm VersionAddendum accept the tokens %%, %C, %d, %h, %i, %j, %k, %L, %l, %n, %p, %r, and %u. .Pp .Cm KnownHostsCommand diff --git a/sshbuf-getput-basic.c b/sshbuf-getput-basic.c index 5c71b0e..77c0a78 100644 --- a/sshbuf-getput-basic.c +++ b/sshbuf-getput-basic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshbuf-getput-basic.c,v 1.13 2022/05/25 06:03:44 djm Exp $ */ +/* $OpenBSD: sshbuf-getput-basic.c,v 1.15 2026/03/03 09:57:25 dtucker Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -15,7 +15,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define SSHBUF_INTERNAL #include "includes.h" #include @@ -24,11 +23,10 @@ #include #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include "ssherr.h" +#define SSHBUF_INTERNAL #include "sshbuf.h" int @@ -45,7 +43,7 @@ sshbuf_get(struct sshbuf *buf, void *v, size_t len) } int -sshbuf_get_u64(struct sshbuf *buf, u_int64_t *valp) +sshbuf_get_u64(struct sshbuf *buf, uint64_t *valp) { const u_char *p = sshbuf_ptr(buf); int r; @@ -58,7 +56,7 @@ sshbuf_get_u64(struct sshbuf *buf, u_int64_t *valp) } int -sshbuf_get_u32(struct sshbuf *buf, u_int32_t *valp) +sshbuf_get_u32(struct sshbuf *buf, uint32_t *valp) { const u_char *p = sshbuf_ptr(buf); int r; @@ -71,7 +69,7 @@ sshbuf_get_u32(struct sshbuf *buf, u_int32_t *valp) } int -sshbuf_get_u16(struct sshbuf *buf, u_int16_t *valp) +sshbuf_get_u16(struct sshbuf *buf, uint16_t *valp) { const u_char *p = sshbuf_ptr(buf); int r; @@ -92,7 +90,7 @@ sshbuf_get_u8(struct sshbuf *buf, u_char *valp) if ((r = sshbuf_consume(buf, 1)) < 0) return r; if (valp != NULL) - *valp = (u_int8_t)*p; + *valp = (uint8_t)*p; return 0; } @@ -124,7 +122,7 @@ check_roffset(const struct sshbuf *buf, size_t offset, size_t len, } int -sshbuf_peek_u64(const struct sshbuf *buf, size_t offset, u_int64_t *valp) +sshbuf_peek_u64(const struct sshbuf *buf, size_t offset, uint64_t *valp) { const u_char *p = NULL; int r; @@ -139,7 +137,7 @@ sshbuf_peek_u64(const struct sshbuf *buf, size_t offset, u_int64_t *valp) } int -sshbuf_peek_u32(const struct sshbuf *buf, size_t offset, u_int32_t *valp) +sshbuf_peek_u32(const struct sshbuf *buf, size_t offset, uint32_t *valp) { const u_char *p = NULL; int r; @@ -154,7 +152,7 @@ sshbuf_peek_u32(const struct sshbuf *buf, size_t offset, u_int32_t *valp) } int -sshbuf_peek_u16(const struct sshbuf *buf, size_t offset, u_int16_t *valp) +sshbuf_peek_u16(const struct sshbuf *buf, size_t offset, uint16_t *valp) { const u_char *p = NULL; int r; @@ -240,7 +238,7 @@ int sshbuf_peek_string_direct(const struct sshbuf *buf, const u_char **valp, size_t *lenp) { - u_int32_t len; + uint32_t len; const u_char *p = sshbuf_ptr(buf); if (valp != NULL) @@ -305,7 +303,7 @@ sshbuf_get_cstring(struct sshbuf *buf, char **valp, size_t *lenp) int sshbuf_get_stringb(struct sshbuf *buf, struct sshbuf *v) { - u_int32_t len; + uint32_t len; u_char *p; int r; @@ -389,7 +387,7 @@ sshbuf_putfv(struct sshbuf *buf, const char *fmt, va_list ap) } int -sshbuf_put_u64(struct sshbuf *buf, u_int64_t val) +sshbuf_put_u64(struct sshbuf *buf, uint64_t val) { u_char *p; int r; @@ -401,7 +399,7 @@ sshbuf_put_u64(struct sshbuf *buf, u_int64_t val) } int -sshbuf_put_u32(struct sshbuf *buf, u_int32_t val) +sshbuf_put_u32(struct sshbuf *buf, uint32_t val) { u_char *p; int r; @@ -413,7 +411,7 @@ sshbuf_put_u32(struct sshbuf *buf, u_int32_t val) } int -sshbuf_put_u16(struct sshbuf *buf, u_int16_t val) +sshbuf_put_u16(struct sshbuf *buf, uint16_t val) { u_char *p; int r; @@ -451,7 +449,7 @@ check_woffset(struct sshbuf *buf, size_t offset, size_t len, u_char **p) } int -sshbuf_poke_u64(struct sshbuf *buf, size_t offset, u_int64_t val) +sshbuf_poke_u64(struct sshbuf *buf, size_t offset, uint64_t val) { u_char *p = NULL; int r; @@ -463,7 +461,7 @@ sshbuf_poke_u64(struct sshbuf *buf, size_t offset, u_int64_t val) } int -sshbuf_poke_u32(struct sshbuf *buf, size_t offset, u_int32_t val) +sshbuf_poke_u32(struct sshbuf *buf, size_t offset, uint32_t val) { u_char *p = NULL; int r; @@ -475,7 +473,7 @@ sshbuf_poke_u32(struct sshbuf *buf, size_t offset, u_int32_t val) } int -sshbuf_poke_u16(struct sshbuf *buf, size_t offset, u_int16_t val) +sshbuf_poke_u16(struct sshbuf *buf, size_t offset, uint16_t val) { u_char *p = NULL; int r; @@ -631,3 +629,41 @@ sshbuf_get_bignum2_bytes_direct(struct sshbuf *buf, } return 0; } + +int +sshbuf_get_nulterminated_string(struct sshbuf *buf, size_t maxlen, + char **valp, size_t *lenp) +{ + const u_char zero = 0; + char *val = NULL; + size_t len = 0; + int r; + + if (valp != NULL) + *valp = NULL; + if (lenp != NULL) + *lenp = 0; + if ((r = sshbuf_find(buf, 0, &zero, sizeof(zero), &len)) != 0) { + if (r == SSH_ERR_INVALID_FORMAT && sshbuf_len(buf) < maxlen) + return SSH_ERR_MESSAGE_INCOMPLETE; + return r; + } + if (len > maxlen) + return SSH_ERR_INVALID_FORMAT; + /* can strdup() because it's definitely nul-terminated */ + if ((val = strdup(sshbuf_ptr(buf))) == NULL) + return SSH_ERR_ALLOC_FAIL; + if ((r = sshbuf_consume(buf, len + 1)) != 0) + goto out; + /* success */ + r = 0; + if (valp != NULL) { + *valp = val; + val = NULL; + } + if (lenp != NULL) + *lenp = len; + out: + free(val); + return r; +} diff --git a/sshbuf-getput-crypto.c b/sshbuf-getput-crypto.c index e7bffe2..7516fd5 100644 --- a/sshbuf-getput-crypto.c +++ b/sshbuf-getput-crypto.c @@ -15,7 +15,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define SSHBUF_INTERNAL #include "includes.h" #include @@ -30,6 +29,7 @@ #endif /* OPENSSL_HAS_ECC */ #include "ssherr.h" +#define SSHBUF_INTERNAL #include "sshbuf.h" int diff --git a/sshbuf-misc.c b/sshbuf-misc.c index 9c5c42b..c8ffdec 100644 --- a/sshbuf-misc.c +++ b/sshbuf-misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshbuf-misc.c,v 1.18 2022/01/22 00:43:43 djm Exp $ */ +/* $OpenBSD: sshbuf-misc.c,v 1.23 2026/03/28 05:10:25 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -22,9 +22,7 @@ #include #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include #include @@ -71,7 +69,7 @@ sshbuf_dump(const struct sshbuf *buf, FILE *f) } char * -sshbuf_dtob16(struct sshbuf *buf) +sshbuf_dtob16(const struct sshbuf *buf) { size_t i, j, len = sshbuf_len(buf); const u_char *p = sshbuf_ptr(buf); @@ -90,6 +88,42 @@ sshbuf_dtob16(struct sshbuf *buf) return ret; } +static int +b16tod(const char v) +{ + if (v >= '0' && v <= '9') + return v - '0'; + if (v >= 'a' && v <= 'f') + return 10 + v - 'a'; + if (v >= 'A' && v <= 'F') + return 10 + v - 'A'; + return -1; +} + +struct sshbuf * +sshbuf_b16tod(const char *b16) +{ + struct sshbuf *ret; + size_t o; + int r, v1, v2; + + if ((ret = sshbuf_new()) == NULL) + return NULL; + for (o = 0; b16[o] != '\0'; o += 2) { + if ((v1 = b16tod(b16[o])) == -1 || + (v2 = b16tod(b16[o + 1])) == -1) { + sshbuf_free(ret); + return NULL; + } + if ((r = sshbuf_put_u8(ret, (u_char)((v1 << 4) | v2))) != 0) { + sshbuf_free(ret); + return NULL; + } + } + /* success */ + return ret; +} + int sshbuf_dtob64(const struct sshbuf *d, struct sshbuf *b64, int wrap) { @@ -176,6 +210,9 @@ sshbuf_dtourlb64(const struct sshbuf *d, struct sshbuf *b64, int wrap) struct sshbuf *b = NULL; size_t i, l; + if (sshbuf_len(d) == 0) + return 0; + if ((b = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; /* Encode using regular base64; we'll transform it once done */ @@ -218,7 +255,7 @@ sshbuf_dup_string(struct sshbuf *buf) size_t l = sshbuf_len(buf); char *r; - if (s == NULL || l > SIZE_MAX) + if (s == NULL || l >= SIZE_MAX) return NULL; /* accept a nul only as the last character in the buffer */ if (l > 0 && (p = memchr(s, '\0', l)) != NULL) { @@ -249,6 +286,20 @@ sshbuf_cmp(const struct sshbuf *b, size_t offset, return 0; } +int +sshbuf_equals(const struct sshbuf *a, const struct sshbuf *b) +{ + if (sshbuf_ptr(a) == NULL || sshbuf_ptr(b) == NULL) + return SSH_ERR_INTERNAL_ERROR; + if (sshbuf_len(a) != sshbuf_len(b)) + return SSH_ERR_MESSAGE_INCOMPLETE; + if (sshbuf_len(a) == 0) + return 0; + if (memcmp(sshbuf_ptr(a), sshbuf_ptr(b), sshbuf_len(a)) != 0) + return SSH_ERR_INVALID_FORMAT; + return 0; +} + int sshbuf_find(const struct sshbuf *b, size_t start_offset, const void *s, size_t len, size_t *offsetp) diff --git a/sshbuf.c b/sshbuf.c index 1b714e5..0dc411c 100644 --- a/sshbuf.c +++ b/sshbuf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshbuf.c,v 1.23 2024/08/14 15:42:18 tobias Exp $ */ +/* $OpenBSD: sshbuf.c,v 1.24 2025/12/29 23:52:09 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -425,3 +425,23 @@ sshbuf_consume_end(struct sshbuf *buf, size_t len) return 0; } +int +sshbuf_consume_upto_child(struct sshbuf *buf, const struct sshbuf *child) +{ + int r; + + if ((r = sshbuf_check_sanity(buf)) != 0 || + (r = sshbuf_check_sanity(child)) != 0) + return r; + /* This function is only used for parent/child buffers */ + if (child->parent != buf) + return SSH_ERR_INVALID_ARGUMENT; + /* Nonsensical if the parent has advanced past the child */ + if (sshbuf_len(child) > sshbuf_len(buf)) + return SSH_ERR_INVALID_ARGUMENT; + /* More paranoia, shouldn't happen */ + if (child->cd < buf->cd) + return SSH_ERR_INTERNAL_ERROR; + /* Advance */ + return sshbuf_consume(buf, sshbuf_len(buf) - sshbuf_len(child)); +} diff --git a/sshbuf.h b/sshbuf.h index 49c32af..b8ccb73 100644 --- a/sshbuf.h +++ b/sshbuf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshbuf.h,v 1.29 2024/08/15 00:51:51 djm Exp $ */ +/* $OpenBSD: sshbuf.h,v 1.35 2026/03/03 09:57:25 dtucker Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -21,6 +21,7 @@ #include #include #include + #ifdef WITH_OPENSSL # include # include @@ -61,7 +62,8 @@ struct sshbuf *sshbuf_fromb(struct sshbuf *buf); * an existing buffer (the string is consumed in the process). * The contents of "buf" must not change in the lifetime of the resultant * buffer. - * Returns pointer to buffer on success, or NULL on allocation failure. + * On success, a pointer to the newly allocated buffer is placed in *bufp. + * Returns 0 on success, or a negative SSH_ERR_* error code on failure. */ int sshbuf_froms(struct sshbuf *buf, struct sshbuf **bufp); @@ -142,6 +144,24 @@ int sshbuf_consume(struct sshbuf *buf, size_t len); */ int sshbuf_consume_end(struct sshbuf *buf, size_t len); +/* + * Consume data from a parent buffer up to that of a child buffer (i.e. + * one created by sshbuf_fromb()). + * + * Intended to be used in a pattern like: + * + * b = sshbuf_fromb(parent); + * sshbuf_get_string(b, &foo, &foostr); + * sshbuf_get_u32(b, &bar); + * sshbuf_consume_upto_child(parent, b); + * + * After which, both "b" and "parent" will point to the same data. + * + * "child" must be a direct child of "buf" (i.e. neither an unrelated buffer + * nor a grandchild) which has consumed data past that of "buf". + */ +int sshbuf_consume_upto_child(struct sshbuf *buf, const struct sshbuf *child); + /* Extract or deposit some bytes */ int sshbuf_get(struct sshbuf *buf, void *v, size_t len); int sshbuf_put(struct sshbuf *buf, const void *v, size_t len); @@ -153,22 +173,22 @@ int sshbuf_putf(struct sshbuf *buf, const char *fmt, ...) int sshbuf_putfv(struct sshbuf *buf, const char *fmt, va_list ap); /* Functions to extract or store big-endian words of various sizes */ -int sshbuf_get_u64(struct sshbuf *buf, u_int64_t *valp); -int sshbuf_get_u32(struct sshbuf *buf, u_int32_t *valp); -int sshbuf_get_u16(struct sshbuf *buf, u_int16_t *valp); +int sshbuf_get_u64(struct sshbuf *buf, uint64_t *valp); +int sshbuf_get_u32(struct sshbuf *buf, uint32_t *valp); +int sshbuf_get_u16(struct sshbuf *buf, uint16_t *valp); int sshbuf_get_u8(struct sshbuf *buf, u_char *valp); -int sshbuf_put_u64(struct sshbuf *buf, u_int64_t val); -int sshbuf_put_u32(struct sshbuf *buf, u_int32_t val); -int sshbuf_put_u16(struct sshbuf *buf, u_int16_t val); +int sshbuf_put_u64(struct sshbuf *buf, uint64_t val); +int sshbuf_put_u32(struct sshbuf *buf, uint32_t val); +int sshbuf_put_u16(struct sshbuf *buf, uint16_t val); int sshbuf_put_u8(struct sshbuf *buf, u_char val); /* Functions to peek at the contents of a buffer without modifying it. */ int sshbuf_peek_u64(const struct sshbuf *buf, size_t offset, - u_int64_t *valp); + uint64_t *valp); int sshbuf_peek_u32(const struct sshbuf *buf, size_t offset, - u_int32_t *valp); + uint32_t *valp); int sshbuf_peek_u16(const struct sshbuf *buf, size_t offset, - u_int16_t *valp); + uint16_t *valp); int sshbuf_peek_u8(const struct sshbuf *buf, size_t offset, u_char *valp); @@ -176,9 +196,9 @@ int sshbuf_peek_u8(const struct sshbuf *buf, size_t offset, * Functions to poke values into an existing buffer (e.g. a length header * to a packet). The destination bytes must already exist in the buffer. */ -int sshbuf_poke_u64(struct sshbuf *buf, size_t offset, u_int64_t val); -int sshbuf_poke_u32(struct sshbuf *buf, size_t offset, u_int32_t val); -int sshbuf_poke_u16(struct sshbuf *buf, size_t offset, u_int16_t val); +int sshbuf_poke_u64(struct sshbuf *buf, size_t offset, uint64_t val); +int sshbuf_poke_u32(struct sshbuf *buf, size_t offset, uint32_t val); +int sshbuf_poke_u16(struct sshbuf *buf, size_t offset, uint16_t val); int sshbuf_poke_u8(struct sshbuf *buf, size_t offset, u_char val); int sshbuf_poke(struct sshbuf *buf, size_t offset, void *v, size_t len); @@ -228,6 +248,10 @@ int sshbuf_put_ec_pkey(struct sshbuf *buf, EVP_PKEY *pkey); # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ +/* Functions to extract or store various non-SSH wire encoded values */ +int sshbuf_get_nulterminated_string(struct sshbuf *buf, size_t maxlen, + char **valp, size_t *lenp); + /* Dump the contents of the buffer in a human-readable format */ void sshbuf_dump(const struct sshbuf *buf, FILE *f); @@ -235,7 +259,9 @@ void sshbuf_dump(const struct sshbuf *buf, FILE *f); void sshbuf_dump_data(const void *s, size_t len, FILE *f); /* Return the hexadecimal representation of the contents of the buffer */ -char *sshbuf_dtob16(struct sshbuf *buf); +char *sshbuf_dtob16(const struct sshbuf *buf); +/* Make a sshbuf from a hex string */ +struct sshbuf *sshbuf_b16tod(const char *b16); /* Encode the contents of the buffer as base64 */ char *sshbuf_dtob64_string(const struct sshbuf *buf, int wrap); @@ -261,6 +287,15 @@ int sshbuf_b64tod(struct sshbuf *buf, const char *b64); int sshbuf_cmp(const struct sshbuf *b, size_t offset, const void *s, size_t len); +/* + * Test whether two buffers have identical contents. + * SSH_ERR_MESSAGE_INCOMPLETE indicates the buffers had differing size. + * SSH_ERR_INVALID_FORMAT indicates the buffers were the same size but + * had differing contents. + * Returns 0 on successful compare (comparing two empty buffers returns 0). + */ +int sshbuf_equals(const struct sshbuf *a, const struct sshbuf *b); + /* * Searches the buffer for the specified string. Returns 0 on success * and updates *offsetp with the offset of the first match, relative to @@ -302,26 +337,26 @@ int sshbuf_read(int, struct sshbuf *, size_t, size_t *) /* Macros for decoding/encoding integers */ #define PEEK_U64(p) \ - (((u_int64_t)(((const u_char *)(p))[0]) << 56) | \ - ((u_int64_t)(((const u_char *)(p))[1]) << 48) | \ - ((u_int64_t)(((const u_char *)(p))[2]) << 40) | \ - ((u_int64_t)(((const u_char *)(p))[3]) << 32) | \ - ((u_int64_t)(((const u_char *)(p))[4]) << 24) | \ - ((u_int64_t)(((const u_char *)(p))[5]) << 16) | \ - ((u_int64_t)(((const u_char *)(p))[6]) << 8) | \ - (u_int64_t)(((const u_char *)(p))[7])) + (((uint64_t)(((const u_char *)(p))[0]) << 56) | \ + ((uint64_t)(((const u_char *)(p))[1]) << 48) | \ + ((uint64_t)(((const u_char *)(p))[2]) << 40) | \ + ((uint64_t)(((const u_char *)(p))[3]) << 32) | \ + ((uint64_t)(((const u_char *)(p))[4]) << 24) | \ + ((uint64_t)(((const u_char *)(p))[5]) << 16) | \ + ((uint64_t)(((const u_char *)(p))[6]) << 8) | \ + (uint64_t)(((const u_char *)(p))[7])) #define PEEK_U32(p) \ - (((u_int32_t)(((const u_char *)(p))[0]) << 24) | \ - ((u_int32_t)(((const u_char *)(p))[1]) << 16) | \ - ((u_int32_t)(((const u_char *)(p))[2]) << 8) | \ - (u_int32_t)(((const u_char *)(p))[3])) + (((uint32_t)(((const u_char *)(p))[0]) << 24) | \ + ((uint32_t)(((const u_char *)(p))[1]) << 16) | \ + ((uint32_t)(((const u_char *)(p))[2]) << 8) | \ + (uint32_t)(((const u_char *)(p))[3])) #define PEEK_U16(p) \ - (((u_int16_t)(((const u_char *)(p))[0]) << 8) | \ - (u_int16_t)(((const u_char *)(p))[1])) + (((uint16_t)(((const u_char *)(p))[0]) << 8) | \ + (uint16_t)(((const u_char *)(p))[1])) #define POKE_U64(p, v) \ do { \ - const u_int64_t __v = (v); \ + const uint64_t __v = (v); \ ((u_char *)(p))[0] = (__v >> 56) & 0xff; \ ((u_char *)(p))[1] = (__v >> 48) & 0xff; \ ((u_char *)(p))[2] = (__v >> 40) & 0xff; \ @@ -333,7 +368,7 @@ int sshbuf_read(int, struct sshbuf *, size_t, size_t *) } while (0) #define POKE_U32(p, v) \ do { \ - const u_int32_t __v = (v); \ + const uint32_t __v = (v); \ ((u_char *)(p))[0] = (__v >> 24) & 0xff; \ ((u_char *)(p))[1] = (__v >> 16) & 0xff; \ ((u_char *)(p))[2] = (__v >> 8) & 0xff; \ @@ -341,7 +376,7 @@ int sshbuf_read(int, struct sshbuf *, size_t, size_t *) } while (0) #define POKE_U16(p, v) \ do { \ - const u_int16_t __v = (v); \ + const uint16_t __v = (v); \ ((u_char *)(p))[0] = (__v >> 8) & 0xff; \ ((u_char *)(p))[1] = __v & 0xff; \ } while (0) diff --git a/sshconnect.c b/sshconnect.c index 7cf6b63..4384277 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.c,v 1.368 2024/04/30 02:10:49 djm Exp $ */ +/* $OpenBSD: sshconnect.c,v 1.382 2026/02/16 00:45:41 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -17,42 +17,31 @@ #include #include -#include #include -#ifdef HAVE_SYS_TIME_H -# include -#endif #include #include #include -#include #include #include #include #include -#ifdef HAVE_PATHS_H #include -#endif #include -#ifdef HAVE_POLL_H #include -#endif #include #include #include #include #include #include -#ifdef HAVE_IFADDRS_H -# include -#endif +#include #include "xmalloc.h" #include "hostfile.h" #include "ssh.h" -#include "sshbuf.h" +#include "compat.h" #include "packet.h" #include "sshkey.h" #include "sshconnect.h" @@ -60,11 +49,8 @@ #include "match.h" #include "misc.h" #include "readconf.h" -#include "atomicio.h" #include "dns.h" #include "monitor_fdpass.h" -#include "ssh2.h" -#include "version.h" #include "authfile.h" #include "ssherr.h" #include "authfd.h" @@ -797,7 +783,7 @@ hostkeys_find_by_key(const char *host, const char *ip, const struct sshkey *key, char **system_hostfiles, u_int num_system_hostfiles, char ***names, u_int *nnames) { - struct find_by_key_ctx ctx = {0, 0, 0, 0, 0}; + struct find_by_key_ctx ctx = {NULL, NULL, NULL, NULL, 0}; u_int i; *names = NULL; @@ -1092,7 +1078,7 @@ check_host_key(char *hostname, const struct ssh_conn_info *cinfo, if (want_cert) { if (sshkey_cert_check_host(host_key, options.host_key_alias == NULL ? - hostname : options.host_key_alias, 0, + hostname : options.host_key_alias, options.ca_sign_algorithms, &fail_reason) != 0) { error("%s", fail_reason); goto fail; @@ -1145,7 +1131,7 @@ check_host_key(char *hostname, const struct ssh_conn_info *cinfo, options.fingerprint_hash, SSH_FP_RANDOMART); if (fp == NULL || ra == NULL) fatal_f("sshkey_fingerprint failed"); - logit("Host key fingerprint is %s\n%s", fp, ra); + logit("Host key fingerprint is: %s\n%s", fp, ra); free(ra); free(fp); } @@ -1196,7 +1182,7 @@ check_host_key(char *hostname, const struct ssh_conn_info *cinfo, options.fingerprint_hash, SSH_FP_RANDOMART); if (fp == NULL || ra == NULL) fatal_f("sshkey_fingerprint failed"); - xextendf(&msg1, "\n", "%s key fingerprint is %s.", + xextendf(&msg1, "\n", "%s key fingerprint is: %s", type, fp); if (options.visual_host_key) xextendf(&msg1, "\n", "%s", ra); @@ -1434,6 +1420,7 @@ check_host_key(char *hostname, const struct ssh_conn_info *cinfo, options.update_hostkeys = 0; } + sshkey_free(raw_key); free(ip); free(host); if (host_hostkeys != NULL) @@ -1514,22 +1501,23 @@ verify_host_key(char *host, struct sockaddr *hostaddr, struct sshkey *host_key, goto out; } - /* Check in RevokedHostKeys file if specified */ - if (options.revoked_host_keys != NULL) { - r = sshkey_check_revoked(host_key, options.revoked_host_keys); + /* Check in RevokedHostKeys files if specified */ + for (i = 0; i < options.num_revoked_host_keys; i++) { + r = sshkey_check_revoked(host_key, + options.revoked_host_keys[i]); switch (r) { case 0: break; /* not revoked */ case SSH_ERR_KEY_REVOKED: error("Host key %s %s revoked by file %s", sshkey_type(host_key), fp, - options.revoked_host_keys); + options.revoked_host_keys[i]); r = -1; goto out; default: error_r(r, "Error checking host key %s %s in " "revoked keys file %s", sshkey_type(host_key), - fp, options.revoked_host_keys); + fp, options.revoked_host_keys[i]); r = -1; goto out; } @@ -1580,6 +1568,14 @@ verify_host_key(char *host, struct sockaddr *hostaddr, struct sshkey *host_key, return r; } +static void +warn_nonpq_kex(void) +{ + logit("** WARNING: connection is not using a post-quantum key exchange algorithm."); + logit("** This session may be vulnerable to \"store now, decrypt later\" attacks."); + logit("** The server may need to be upgraded. See https://openssh.com/pq.html"); +} + /* * Starts a dialog with the server, and authenticates the current user on the * server. This does not need any extra privileges. The basic connection @@ -1604,9 +1600,15 @@ ssh_login(struct ssh *ssh, Sensitive *sensitive, const char *orighost, lowercase(host); /* Exchange protocol version identification strings with the server. */ - if ((r = kex_exchange_identification(ssh, timeout_ms, NULL)) != 0) + if ((r = kex_exchange_identification(ssh, timeout_ms, + options.version_addendum)) != 0) sshpkt_fatal(ssh, r, "banner exchange"); + if ((ssh->compat & SSH_BUG_NOREKEY)) { + logit("Warning: this server does not support rekeying."); + logit("This session will eventually fail"); + } + /* Put the connection into non-blocking mode. */ ssh_packet_set_nonblocking(ssh); @@ -1614,6 +1616,10 @@ ssh_login(struct ssh *ssh, Sensitive *sensitive, const char *orighost, /* authenticate user */ debug("Authenticating to %s:%d as '%s'", host, port, server_user); ssh_kex2(ssh, host, hostaddr, port, cinfo); + if (!options.kex_algorithms_set && ssh->kex != NULL && + ssh->kex->name != NULL && options.warn_weak_crypto && + !kex_is_pq_from_name(ssh->kex->name)) + warn_nonpq_kex(); ssh_userauth2(ssh, local_user, server_user, host, sensitive); free(local_user); free(host); @@ -1625,12 +1631,8 @@ show_other_keys(struct hostkeys *hostkeys, struct sshkey *key) { int type[] = { KEY_RSA, -#ifdef WITH_DSA - KEY_DSA, -#endif KEY_ECDSA, KEY_ED25519, - KEY_XMSS, -1 }; int i, ret = 0; @@ -1753,7 +1755,7 @@ maybe_add_key_to_agent(const char *authfile, struct sshkey *private, if ((r = ssh_add_identity_constrained(auth_sock, private, comment == NULL ? authfile : comment, options.add_keys_to_agent_lifespan, - (options.add_keys_to_agent == 3), 0, skprovider, NULL, 0)) == 0) + (options.add_keys_to_agent == 3), skprovider, NULL, 0)) == 0) debug("identity added to agent: %s", authfile); else debug("could not add identity to agent: %s (%d)", authfile, r); diff --git a/sshconnect.h b/sshconnect.h index 8b0466f..4c19490 100644 --- a/sshconnect.h +++ b/sshconnect.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.h,v 1.48 2024/04/30 02:10:49 djm Exp $ */ +/* $OpenBSD: sshconnect.h,v 1.50 2026/02/13 01:04:47 jsg Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -50,11 +50,9 @@ struct ssh_conn_info { struct addrinfo; struct ssh; struct hostkeys; -struct ssh_conn_info; -/* default argument for client percent expansions */ -#define DEFAULT_CLIENT_PERCENT_EXPAND_ARGS(conn_info) \ - "C", conn_info->conn_hash_hex, \ +/* default argument for client percent expansions, minus remote user */ +#define DEFAULT_CLIENT_PERCENT_EXPAND_ARGS_NOUSER(conn_info) \ "L", conn_info->shorthost, \ "i", conn_info->uidstr, \ "k", conn_info->keyalias, \ @@ -63,10 +61,15 @@ struct ssh_conn_info; "p", conn_info->portstr, \ "d", conn_info->homedir, \ "h", conn_info->remhost, \ - "r", conn_info->remuser, \ "u", conn_info->locuser, \ "j", conn_info->jmphost +/* same plus remote user and hash which has user as a component */ +#define DEFAULT_CLIENT_PERCENT_EXPAND_ARGS(conn_info) \ + DEFAULT_CLIENT_PERCENT_EXPAND_ARGS_NOUSER(conn_info), \ + "C", conn_info->conn_hash_hex, \ + "r", conn_info->remuser + int ssh_connect(struct ssh *, const char *, const char *, struct addrinfo *, struct sockaddr_storage *, u_short, int, int *, int); diff --git a/sshconnect2.c b/sshconnect2.c index 86f1fb0..478a9a5 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.375 2024/09/09 02:39:57 djm Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.385 2026/04/02 07:48:13 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -29,12 +29,12 @@ #include #include #include +#include #include #include #include #include -#include #include #include #include @@ -45,8 +45,6 @@ #include #endif -#include "openbsd-compat/sys-queue.h" - #include "xmalloc.h" #include "ssh.h" #include "ssh2.h" @@ -58,7 +56,6 @@ #include "kex.h" #include "sshconnect.h" #include "authfile.h" -#include "dh.h" #include "authfd.h" #include "log.h" #include "misc.h" @@ -68,7 +65,6 @@ #include "canohost.h" #include "msg.h" #include "pathnames.h" -#include "uidswap.h" #include "hostfile.h" #include "ssherr.h" #include "utf8.h" @@ -89,6 +85,7 @@ extern Options options; static char *xxx_host; static struct sockaddr *xxx_hostaddr; static const struct ssh_conn_info *xxx_conn_info; +static int key_type_allowed(struct sshkey *, const char *); static int verify_host_key_callback(struct sshkey *hostkey, struct ssh *ssh) @@ -98,6 +95,10 @@ verify_host_key_callback(struct sshkey *hostkey, struct ssh *ssh) if ((r = sshkey_check_rsa_length(hostkey, options.required_rsa_size)) != 0) fatal_r(r, "Bad server host key"); + if (!key_type_allowed(hostkey, options.hostkeyalgorithms)) { + fatal("Server host key %s not in HostKeyAlgorithms", + sshkey_ssh_name(hostkey)); + } if (verify_host_key(xxx_host, xxx_hostaddr, hostkey, xxx_conn_info) != 0) fatal("Host key verification failed."); @@ -347,14 +348,14 @@ struct cauthmethod { int *batch_flag; /* flag in option struct that disables method */ }; -static int input_userauth_service_accept(int, u_int32_t, struct ssh *); -static int input_userauth_success(int, u_int32_t, struct ssh *); -static int input_userauth_failure(int, u_int32_t, struct ssh *); -static int input_userauth_banner(int, u_int32_t, struct ssh *); -static int input_userauth_error(int, u_int32_t, struct ssh *); -static int input_userauth_info_req(int, u_int32_t, struct ssh *); -static int input_userauth_pk_ok(int, u_int32_t, struct ssh *); -static int input_userauth_passwd_changereq(int, u_int32_t, struct ssh *); +static int input_userauth_service_accept(int, uint32_t, struct ssh *); +static int input_userauth_success(int, uint32_t, struct ssh *); +static int input_userauth_failure(int, uint32_t, struct ssh *); +static int input_userauth_banner(int, uint32_t, struct ssh *); +static int input_userauth_error(int, uint32_t, struct ssh *); +static int input_userauth_info_req(int, uint32_t, struct ssh *); +static int input_userauth_pk_ok(int, uint32_t, struct ssh *); +static int input_userauth_passwd_changereq(int, uint32_t, struct ssh *); static int userauth_none(struct ssh *); static int userauth_pubkey(struct ssh *); @@ -365,10 +366,10 @@ static int userauth_hostbased(struct ssh *); #ifdef GSSAPI static int userauth_gssapi(struct ssh *); static void userauth_gssapi_cleanup(struct ssh *); -static int input_gssapi_response(int type, u_int32_t, struct ssh *); -static int input_gssapi_token(int type, u_int32_t, struct ssh *); -static int input_gssapi_error(int, u_int32_t, struct ssh *); -static int input_gssapi_errtok(int, u_int32_t, struct ssh *); +static int input_gssapi_response(int type, uint32_t, struct ssh *); +static int input_gssapi_token(int type, uint32_t, struct ssh *); +static int input_gssapi_error(int, uint32_t, struct ssh *); +static int input_gssapi_errtok(int, uint32_t, struct ssh *); #endif void userauth(struct ssh *, char *); @@ -488,7 +489,7 @@ ssh_userauth2(struct ssh *ssh, const char *local_user, } static int -input_userauth_service_accept(int type, u_int32_t seq, struct ssh *ssh) +input_userauth_service_accept(int type, uint32_t seq, struct ssh *ssh) { int r; @@ -559,14 +560,14 @@ userauth(struct ssh *ssh, char *authlist) } static int -input_userauth_error(int type, u_int32_t seq, struct ssh *ssh) +input_userauth_error(int type, uint32_t seq, struct ssh *ssh) { fatal_f("bad message during authentication: type %d", type); return 0; } static int -input_userauth_banner(int type, u_int32_t seq, struct ssh *ssh) +input_userauth_banner(int type, uint32_t seq, struct ssh *ssh) { char *msg = NULL; size_t len; @@ -585,7 +586,7 @@ input_userauth_banner(int type, u_int32_t seq, struct ssh *ssh) } static int -input_userauth_success(int type, u_int32_t seq, struct ssh *ssh) +input_userauth_success(int type, uint32_t seq, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; @@ -604,7 +605,7 @@ input_userauth_success(int type, u_int32_t seq, struct ssh *ssh) #if 0 static int -input_userauth_success_unexpected(int type, u_int32_t seq, struct ssh *ssh) +input_userauth_success_unexpected(int type, uint32_t seq, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; @@ -618,7 +619,7 @@ input_userauth_success_unexpected(int type, u_int32_t seq, struct ssh *ssh) #endif static int -input_userauth_failure(int type, u_int32_t seq, struct ssh *ssh) +input_userauth_failure(int type, uint32_t seq, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; char *authlist = NULL; @@ -678,7 +679,7 @@ format_identity(Identity *id) } static int -input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) +input_userauth_pk_ok(int type, uint32_t seq, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; struct sshkey *key = NULL; @@ -885,7 +886,7 @@ process_gssapi_token(struct ssh *ssh, gss_buffer_t recv_tok) } static int -input_gssapi_response(int type, u_int32_t plen, struct ssh *ssh) +input_gssapi_response(int type, uint32_t plen, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; Gssctxt *gssctxt; @@ -929,7 +930,7 @@ input_gssapi_response(int type, u_int32_t plen, struct ssh *ssh) } static int -input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh) +input_gssapi_token(int type, uint32_t plen, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; gss_buffer_desc recv_tok; @@ -961,7 +962,7 @@ input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh) } static int -input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh) +input_gssapi_errtok(int type, uint32_t plen, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; Gssctxt *gssctxt; @@ -995,7 +996,7 @@ input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh) } static int -input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh) +input_gssapi_error(int type, uint32_t plen, struct ssh *ssh) { char *msg = NULL; char *lang = NULL; @@ -1072,13 +1073,14 @@ userauth_passwd(struct ssh *ssh) * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST */ static int -input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh) +input_userauth_passwd_changereq(int type, uint32_t seqnr, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; char *info = NULL, *lang = NULL, *password = NULL, *retype = NULL; char prompt[256]; const char *host; - int r; + int r, addnl; + size_t len; debug2("input_userauth_passwd_changereq"); @@ -1090,8 +1092,10 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh) if ((r = sshpkt_get_cstring(ssh, &info, NULL)) != 0 || (r = sshpkt_get_cstring(ssh, &lang, NULL)) != 0) goto out; - if (strlen(info) > 0) - logit("%s", info); + if ((len = strlen(info)) > 0) { + addnl = info[len] != '\n'; + fmprintf(stderr, "%s%s", info, addnl ? "\n" : ""); + } if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 || (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || @@ -1273,7 +1277,8 @@ identity_sign(struct identity *id, u_char **sigp, size_t *lenp, * PKCS#11 tokens may not support all signature algorithms, * so check what we get back. */ - if ((r = sshkey_check_sigtype(*sigp, *lenp, alg)) != 0) { + if ((id->key->flags & SSHKEY_FLAG_EXT) != 0 && + (r = sshkey_check_sigtype(*sigp, *lenp, alg)) != 0) { debug_fr(r, "sshkey_check_sigtype"); goto out; } @@ -1341,7 +1346,7 @@ sign_and_send_pubkey(struct ssh *ssh, Identity *id) * This will try to set sign_id to the private key that will perform * the signature. */ - if (sshkey_is_cert(id->key)) { + if (id->agent_fd == -1 && sshkey_is_cert(id->key)) { TAILQ_FOREACH(private_id, &authctxt->keys, next) { if (sshkey_equal_public(id->key, private_id->key) && id->key->type != private_id->key->type) { @@ -1598,34 +1603,37 @@ load_identity_file(Identity *id) } static int -key_type_allowed_by_config(struct sshkey *key) +key_type_allowed(struct sshkey *key, const char *allowlist) { - if (match_pattern_list(sshkey_ssh_name(key), - options.pubkey_accepted_algos, 0) == 1) + if (match_pattern_list(sshkey_ssh_name(key), allowlist, 0) == 1) return 1; /* RSA keys/certs might be allowed by alternate signature types */ switch (key->type) { case KEY_RSA: - if (match_pattern_list("rsa-sha2-512", - options.pubkey_accepted_algos, 0) == 1) + if (match_pattern_list("rsa-sha2-512", allowlist, 0) == 1) return 1; - if (match_pattern_list("rsa-sha2-256", - options.pubkey_accepted_algos, 0) == 1) + if (match_pattern_list("rsa-sha2-256", allowlist, 0) == 1) return 1; break; case KEY_RSA_CERT: if (match_pattern_list("rsa-sha2-512-cert-v01@openssh.com", - options.pubkey_accepted_algos, 0) == 1) + allowlist, 0) == 1) return 1; if (match_pattern_list("rsa-sha2-256-cert-v01@openssh.com", - options.pubkey_accepted_algos, 0) == 1) + allowlist, 0) == 1) return 1; break; } return 0; } +static int +key_type_allowed_by_config(struct sshkey *key) +{ + return key_type_allowed(key, options.pubkey_accepted_algos); +} + /* obtain a list of keys from the agent */ static int get_agent_identities(struct ssh *ssh, int *agent_fdp, @@ -1815,7 +1823,7 @@ pubkey_prepare(struct ssh *ssh, Authctxt *authctxt) TAILQ_REMOVE(preferred, id, next); sshkey_free(id->key); free(id->filename); - memset(id, 0, sizeof(*id)); + freezero(id, sizeof(*id)); } /* List the keys we plan on using */ TAILQ_FOREACH_SAFE(id, preferred, next, id2) { @@ -1888,10 +1896,8 @@ userauth_pubkey(struct ssh *ssh) debug("Trying private key: %s", id->filename); id->key = load_identity_file(id); if (id->key != NULL) { - if (id->key != NULL) { - id->isprivate = 1; - sent = sign_and_send_pubkey(ssh, id); - } + id->isprivate = 1; + sent = sign_and_send_pubkey(ssh, id); sshkey_free(id->key); id->key = NULL; id->isprivate = 0; @@ -1940,14 +1946,15 @@ userauth_kbdint(struct ssh *ssh) * parse INFO_REQUEST, prompt user and send INFO_RESPONSE */ static int -input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh) +input_userauth_info_req(int type, uint32_t seq, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; char *name = NULL, *inst = NULL, *lang = NULL, *prompt = NULL; char *display_prompt = NULL, *response = NULL; u_char echo = 0; u_int num_prompts, i; - int r; + int r, addnl; + size_t len; debug2_f("entering"); @@ -1960,10 +1967,14 @@ input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh) (r = sshpkt_get_cstring(ssh, &inst, NULL)) != 0 || (r = sshpkt_get_cstring(ssh, &lang, NULL)) != 0) goto out; - if (strlen(name) > 0) - logit("%s", name); - if (strlen(inst) > 0) - logit("%s", inst); + if ((len = strlen(name)) > 0) { + addnl = name[len] != '\n'; + fmprintf(stderr, "%s%s", name, addnl ? "\n" : ""); + } + if ((len = strlen(inst)) > 0) { + addnl = inst[len] != '\n'; + fmprintf(stderr, "%s%s", inst, addnl ? "\n" : ""); + } if ((r = sshpkt_get_u32(ssh, &num_prompts)) != 0) goto out; diff --git a/sshd-auth.c b/sshd-auth.c new file mode 100644 index 0000000..76350a2 --- /dev/null +++ b/sshd-auth.c @@ -0,0 +1,867 @@ +/* $OpenBSD: sshd-auth.c,v 1.14 2026/03/11 09:10:59 dtucker Exp $ */ +/* + * SSH2 implementation: + * Privilege Separation: + * + * Copyright (c) 2000, 2001, 2002 Markus Friedl. All rights reserved. + * Copyright (c) 2002 Niels Provos. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef WITH_OPENSSL +#include +#include +#endif + +#include "xmalloc.h" +#include "ssh.h" +#include "ssh2.h" +#include "sshpty.h" +#include "packet.h" +#include "log.h" +#include "sshbuf.h" +#include "misc.h" +#include "match.h" +#include "servconf.h" +#include "uidswap.h" +#include "compat.h" +#include "cipher.h" +#include "digest.h" +#include "sshkey.h" +#include "kex.h" +#include "authfile.h" +#include "pathnames.h" +#include "atomicio.h" +#include "canohost.h" +#include "hostfile.h" +#include "auth.h" +#include "authfd.h" +#include "msg.h" +#include "dispatch.h" +#include "channels.h" +#include "session.h" +#include "monitor.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif +#include "monitor_wrap.h" +#include "auth-options.h" +#include "version.h" +#include "ssherr.h" +#include "sk-api.h" +#include "srclimit.h" +#include "ssh-sandbox.h" +#include "dh.h" + +/* Privsep fds */ +#define PRIVSEP_MONITOR_FD (STDERR_FILENO + 1) +#define PRIVSEP_LOG_FD (STDERR_FILENO + 2) +#define PRIVSEP_MIN_FREE_FD (STDERR_FILENO + 3) + +extern char *__progname; + +/* Server configuration options. */ +ServerOptions options; + +/* Name of the server configuration file. */ +char *config_file_name = _PATH_SERVER_CONFIG_FILE; + +/* + * Debug mode flag. This can be set on the command line. If debug + * mode is enabled, extra debugging output will be sent to the system + * log, the daemon will not go to background, and will exit after processing + * the first connection. + */ +int debug_flag = 0; + +/* Flag indicating that the daemon is being started from inetd. */ +static int inetd_flag = 0; + +/* Saved arguments to main(). */ +static char **saved_argv; +static int saved_argc; + + +/* Daemon's agent connection */ +int auth_sock = -1; +static int have_agent = 0; + +u_int num_hostkeys; +struct sshkey **host_pubkeys; /* all public host keys */ +struct sshkey **host_certificates; /* all public host certificates */ + +/* record remote hostname or ip */ +u_int utmp_len = HOST_NAME_MAX+1; + +/* variables used for privilege separation */ +struct monitor *pmonitor = NULL; +int privsep_is_preauth = 1; +static int privsep_chroot = 1; + +/* global connection state and authentication contexts */ +Authctxt *the_authctxt = NULL; +struct ssh *the_active_state; + +/* global key/cert auth options. XXX move to permanent ssh->authctxt? */ +struct sshauthopt *auth_opts = NULL; + +/* sshd_config buffer */ +struct sshbuf *cfg; + +/* Included files from the configuration file */ +struct include_list includes = TAILQ_HEAD_INITIALIZER(includes); + +/* message to be displayed after login */ +struct sshbuf *loginmsg; + +/* Prototypes for various functions defined later in this file. */ +static void do_ssh2_kex(struct ssh *); + +/* Unprivileged user */ +struct passwd *privsep_pw = NULL; + +#ifndef HAVE_PLEDGE +static struct ssh_sandbox *box; +#endif + +/* XXX stub */ +int +mm_is_monitor(void) +{ + return 0; +} + +static void +privsep_child_demote(void) +{ + gid_t gidset[1]; + +#ifndef HAVE_PLEDGE + if ((box = ssh_sandbox_init(pmonitor)) == NULL) + fatal_f("ssh_sandbox_init failed"); +#endif + /* Demote the child */ + if (privsep_chroot) { + /* Change our root directory */ + if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1) + fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR, + strerror(errno)); + if (chdir("/") == -1) + fatal("chdir(\"/\"): %s", strerror(errno)); + + /* + * Drop our privileges + * NB. Can't use setusercontext() after chroot. + */ + debug3("privsep user:group %u:%u", (u_int)privsep_pw->pw_uid, + (u_int)privsep_pw->pw_gid); + gidset[0] = privsep_pw->pw_gid; + if (setgroups(1, gidset) == -1) + fatal("setgroups: %.100s", strerror(errno)); + permanently_set_uid(privsep_pw); + } + + /* sandbox ourselves */ +#ifdef HAVE_PLEDGE + if (pledge("stdio", NULL) == -1) + fatal_f("pledge()"); +#else + ssh_sandbox_child(box); +#endif +} + +static void +append_hostkey_type(struct sshbuf *b, const char *s) +{ + int r; + + if (match_pattern_list(s, options.hostkeyalgorithms, 0) != 1) { + debug3_f("%s key not permitted by HostkeyAlgorithms", s); + return; + } + if ((r = sshbuf_putf(b, "%s%s", sshbuf_len(b) > 0 ? "," : "", s)) != 0) + fatal_fr(r, "sshbuf_putf"); +} + +static char * +list_hostkey_types(void) +{ + struct sshbuf *b; + struct sshkey *key; + char *ret; + u_int i; + + if ((b = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + for (i = 0; i < options.num_host_key_files; i++) { + key = host_pubkeys[i]; + if (key == NULL) + continue; + switch (key->type) { + case KEY_RSA: + /* for RSA we also support SHA2 signatures */ + append_hostkey_type(b, "rsa-sha2-512"); + append_hostkey_type(b, "rsa-sha2-256"); + /* FALLTHROUGH */ + case KEY_ECDSA: + case KEY_ED25519: + case KEY_ECDSA_SK: + case KEY_ED25519_SK: + append_hostkey_type(b, sshkey_ssh_name(key)); + break; + } + /* If the private key has a cert peer, then list that too */ + key = host_certificates[i]; + if (key == NULL) + continue; + switch (key->type) { + case KEY_RSA_CERT: + /* for RSA we also support SHA2 signatures */ + append_hostkey_type(b, + "rsa-sha2-512-cert-v01@openssh.com"); + append_hostkey_type(b, + "rsa-sha2-256-cert-v01@openssh.com"); + /* FALLTHROUGH */ + case KEY_ECDSA_CERT: + case KEY_ED25519_CERT: + case KEY_ECDSA_SK_CERT: + case KEY_ED25519_SK_CERT: + append_hostkey_type(b, sshkey_ssh_name(key)); + break; + } + } + if ((ret = sshbuf_dup_string(b)) == NULL) + fatal_f("sshbuf_dup_string failed"); + sshbuf_free(b); + debug_f("%s", ret); + return ret; +} + +struct sshkey * +get_hostkey_public_by_type(int type, int nid, struct ssh *ssh) +{ + u_int i; + struct sshkey *key; + + for (i = 0; i < options.num_host_key_files; i++) { + switch (type) { + case KEY_RSA_CERT: + case KEY_ECDSA_CERT: + case KEY_ED25519_CERT: + case KEY_ECDSA_SK_CERT: + case KEY_ED25519_SK_CERT: + key = host_certificates[i]; + break; + default: + key = host_pubkeys[i]; + break; + } + if (key == NULL || key->type != type) + continue; + switch (type) { + case KEY_ECDSA: + case KEY_ECDSA_SK: + case KEY_ECDSA_CERT: + case KEY_ECDSA_SK_CERT: + if (key->ecdsa_nid != nid) + continue; + /* FALLTHROUGH */ + default: + return key; + } + } + return NULL; +} + +/* XXX remove */ +struct sshkey * +get_hostkey_private_by_type(int type, int nid, struct ssh *ssh) +{ + return NULL; +} + +/* XXX remove */ +struct sshkey * +get_hostkey_by_index(int ind) +{ + return NULL; +} + +struct sshkey * +get_hostkey_public_by_index(int ind, struct ssh *ssh) +{ + if (ind < 0 || (u_int)ind >= options.num_host_key_files) + return (NULL); + return host_pubkeys[ind]; +} + +int +get_hostkey_index(struct sshkey *key, int compare, struct ssh *ssh) +{ + u_int i; + + for (i = 0; i < options.num_host_key_files; i++) { + if (sshkey_is_cert(key)) { + if (key == host_certificates[i] || + (compare && host_certificates[i] && + sshkey_equal(key, host_certificates[i]))) + return (i); + } else { + if (key == host_pubkeys[i] || + (compare && host_pubkeys[i] && + sshkey_equal(key, host_pubkeys[i]))) + return (i); + } + } + return (-1); +} + +static void +usage(void) +{ + fprintf(stderr, "%s, %s\n", SSH_VERSION, SSH_OPENSSL_VERSION); + fprintf(stderr, +"usage: sshd [-46DdeGiqTtV] [-C connection_spec] [-c host_cert_file]\n" +" [-E log_file] [-f config_file] [-g login_grace_time]\n" +" [-h host_key_file] [-o option] [-p port] [-u len]\n" + ); + exit(1); +} + +static void +parse_hostkeys(struct sshbuf *hostkeys) +{ + int r; + u_int num_keys = 0; + struct sshkey *k; + const u_char *cp; + size_t len; + + while (sshbuf_len(hostkeys) != 0) { + if (num_keys > 2048) + fatal_f("too many hostkeys"); + host_pubkeys = xrecallocarray(host_pubkeys, + num_keys, num_keys + 1, sizeof(*host_pubkeys)); + host_certificates = xrecallocarray(host_certificates, + num_keys, num_keys + 1, sizeof(*host_certificates)); + /* public key */ + k = NULL; + if ((r = sshbuf_get_string_direct(hostkeys, &cp, &len)) != 0) + fatal_fr(r, "extract pubkey"); + if (len != 0 && (r = sshkey_from_blob(cp, len, &k)) != 0) + fatal_fr(r, "parse pubkey"); + host_pubkeys[num_keys] = k; + if (k) + debug2_f("key %u: %s", num_keys, sshkey_ssh_name(k)); + /* certificate */ + k = NULL; + if ((r = sshbuf_get_string_direct(hostkeys, &cp, &len)) != 0) + fatal_fr(r, "extract pubkey"); + if (len != 0 && (r = sshkey_from_blob(cp, len, &k)) != 0) + fatal_fr(r, "parse pubkey"); + host_certificates[num_keys] = k; + if (k) + debug2_f("cert %u: %s", num_keys, sshkey_ssh_name(k)); + num_keys++; + } + num_hostkeys = num_keys; +} + +static void +recv_privsep_state(struct ssh *ssh, struct sshbuf *conf, + uint64_t *timing_secretp) +{ + struct sshbuf *hostkeys; + + debug3_f("begin"); + + mm_get_state(ssh, &includes, conf, NULL, timing_secretp, + &hostkeys, NULL, NULL, NULL, NULL); + parse_hostkeys(hostkeys); + + sshbuf_free(hostkeys); + + debug3_f("done"); +} + +/* + * Main program for the daemon. + */ +int +main(int ac, char **av) +{ + struct ssh *ssh = NULL; + extern char *optarg; + extern int optind; + int r, opt, have_key = 0; + int sock_in = -1, sock_out = -1, rexeced_flag = 0; + char *line; + u_int i; + mode_t new_umask; + Authctxt *authctxt; + struct connection_info *connection_info = NULL; + sigset_t sigmask; + uint64_t timing_secret = 0; + + closefrom(PRIVSEP_MIN_FREE_FD); + sigemptyset(&sigmask); + sigprocmask(SIG_SETMASK, &sigmask, NULL); + +#ifdef HAVE_SECUREWARE + (void)set_auth_parameters(ac, av); +#endif + __progname = ssh_get_progname(av[0]); + + /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ + saved_argc = ac; + saved_argv = xcalloc(ac + 1, sizeof(*saved_argv)); + for (i = 0; (int)i < ac; i++) + saved_argv[i] = xstrdup(av[i]); + saved_argv[i] = NULL; + + seed_rng(); + +#ifndef HAVE_SETPROCTITLE + /* Prepare for later setproctitle emulation */ + compat_init_setproctitle(ac, av); + av = saved_argv; +#endif + + /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ + sanitise_stdfd(); + + /* Initialize configuration options to their default values. */ + initialize_server_options(&options); + + /* Parse command-line arguments. */ + while ((opt = getopt(ac, av, + "C:E:b:c:f:g:h:k:o:p:u:46DGQRTdeiqrtV")) != -1) { + switch (opt) { + case '4': + options.address_family = AF_INET; + break; + case '6': + options.address_family = AF_INET6; + break; + case 'f': + config_file_name = optarg; + break; + case 'c': + servconf_add_hostcert("[command-line]", 0, + &options, optarg); + break; + case 'd': + if (debug_flag == 0) { + debug_flag = 1; + options.log_level = SYSLOG_LEVEL_DEBUG1; + } else if (options.log_level < SYSLOG_LEVEL_DEBUG3) + options.log_level++; + break; + case 'D': + case 'E': + case 'e': + /* ignore */ + break; + case 'i': + inetd_flag = 1; + break; + case 'r': + /* ignore */ + break; + case 'R': + rexeced_flag = 1; + break; + case 'Q': + /* ignored */ + break; + case 'q': + options.log_level = SYSLOG_LEVEL_QUIET; + break; + case 'b': + /* protocol 1, ignored */ + break; + case 'p': + options.ports_from_cmdline = 1; + if (options.num_ports >= MAX_PORTS) { + fprintf(stderr, "too many ports.\n"); + exit(1); + } + options.ports[options.num_ports++] = a2port(optarg); + if (options.ports[options.num_ports-1] <= 0) { + fprintf(stderr, "Bad port number.\n"); + exit(1); + } + break; + case 'g': + if ((options.login_grace_time = convtime(optarg)) == -1) { + fprintf(stderr, "Invalid login grace time.\n"); + exit(1); + } + break; + case 'k': + /* protocol 1, ignored */ + break; + case 'h': + servconf_add_hostkey("[command-line]", 0, + &options, optarg, 1); + break; + case 't': + case 'T': + case 'G': + fatal("test/dump modes not supported"); + break; + case 'C': + connection_info = server_get_connection_info(ssh, 0, 0); + if (parse_server_match_testspec(connection_info, + optarg) == -1) + exit(1); + break; + case 'u': + utmp_len = (u_int)strtonum(optarg, 0, HOST_NAME_MAX+1+1, NULL); + if (utmp_len > HOST_NAME_MAX+1) { + fprintf(stderr, "Invalid utmp length.\n"); + exit(1); + } + break; + case 'o': + line = xstrdup(optarg); + if (process_server_config_line(&options, line, + "command-line", 0, NULL, NULL, &includes) != 0) + exit(1); + free(line); + break; + case 'V': + fprintf(stderr, "%s, %s\n", + SSH_VERSION, SSH_OPENSSL_VERSION); + exit(0); + default: + usage(); + break; + } + } + + if (!rexeced_flag) + fatal("sshd-auth should not be executed directly"); + + log_init(__progname, + options.log_level == SYSLOG_LEVEL_NOT_SET ? + SYSLOG_LEVEL_INFO : options.log_level, + options.log_facility == SYSLOG_FACILITY_NOT_SET ? + SYSLOG_FACILITY_AUTH : options.log_facility, 1); + + /* XXX can't use monitor_init(); it makes fds */ + pmonitor = xcalloc(1, sizeof(*pmonitor)); + pmonitor->m_sendfd = pmonitor->m_log_recvfd = -1; + pmonitor->m_recvfd = PRIVSEP_MONITOR_FD; + pmonitor->m_log_sendfd = PRIVSEP_LOG_FD; + set_log_handler(mm_log_handler, pmonitor); + + /* Check that there are no remaining arguments. */ + if (optind < ac) { + fprintf(stderr, "Extra argument %s.\n", av[optind]); + exit(1); + } + + /* Connection passed by stdin/out */ + if (inetd_flag) { + /* + * NB. must be different fd numbers for the !socket case, + * as packet_connection_is_on_socket() depends on this. + */ + sock_in = dup(STDIN_FILENO); + sock_out = dup(STDOUT_FILENO); + } else { + /* rexec case; accept()ed socket in ancestor listener */ + sock_in = sock_out = dup(STDIN_FILENO); + } + + if (stdfd_devnull(1, 1, 0) == -1) + error("stdfd_devnull failed"); + debug("network sockets: %d, %d", sock_in, sock_out); + + /* + * Register our connection. This turns encryption off because we do + * not have a key. + */ + if ((ssh = ssh_packet_set_connection(NULL, sock_in, sock_out)) == NULL) + fatal("Unable to create connection"); + the_active_state = ssh; + ssh_packet_set_server(ssh); + pmonitor->m_pkex = &ssh->kex; + + /* Fetch our configuration */ + if ((cfg = sshbuf_new()) == NULL) + fatal("sshbuf_new config buf failed"); + setproctitle("%s", "[session-auth early]"); + recv_privsep_state(ssh, cfg, &timing_secret); + parse_server_config(&options, "rexec", cfg, &includes, NULL, 1); + /* Fill in default values for those options not explicitly set. */ + fill_default_server_options(&options); + options.timing_secret = timing_secret; /* XXX eliminate from unpriv */ + ssh_packet_set_qos(ssh, options.ip_qos_interactive, + options.ip_qos_bulk); + + /* Reinit logging in case config set Level, Facility or Verbose. */ + log_init(__progname, options.log_level, options.log_facility, 1); + set_log_handler(mm_log_handler, pmonitor); + + debug("sshd-auth version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION); + + /* Store privilege separation user for later use if required. */ + privsep_chroot = (getuid() == 0 || geteuid() == 0); + if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) { + if (privsep_chroot || options.kerberos_authentication) + fatal("Privilege separation user %s does not exist", + SSH_PRIVSEP_USER); + } else { + privsep_pw = pwcopy(privsep_pw); + freezero(privsep_pw->pw_passwd, strlen(privsep_pw->pw_passwd)); + privsep_pw->pw_passwd = xstrdup("*"); + } + endpwent(); + +#ifdef WITH_OPENSSL + if (options.moduli_file != NULL) + dh_set_moduli_file(options.moduli_file); +#endif + + if (options.host_key_agent) { + if (strcmp(options.host_key_agent, SSH_AUTHSOCKET_ENV_NAME)) + setenv(SSH_AUTHSOCKET_ENV_NAME, + options.host_key_agent, 1); + if ((r = ssh_get_authentication_socket(NULL)) == 0) + have_agent = 1; + else + error_r(r, "Could not connect to agent \"%s\"", + options.host_key_agent); + } + + if (options.num_host_key_files != num_hostkeys) { + fatal("internal error: hostkeys confused (config %u recvd %u)", + options.num_host_key_files, num_hostkeys); + } + + for (i = 0; i < options.num_host_key_files; i++) { + if (host_pubkeys[i] != NULL) { + have_key = 1; + break; + } + } + if (!have_key) + fatal("internal error: received no hostkeys"); + + /* Ensure that umask disallows at least group and world write */ + new_umask = umask(0077) | 0022; + (void) umask(new_umask); + + /* Initialize the log (it is reinitialized below in case we forked). */ + log_init(__progname, options.log_level, options.log_facility, 1); + set_log_handler(mm_log_handler, pmonitor); + for (i = 0; i < options.num_log_verbose; i++) + log_verbose_add(options.log_verbose[i]); + + /* + * Chdir to the root directory so that the current disk can be + * unmounted if desired. + */ + if (chdir("/") == -1) + error("chdir(\"/\"): %s", strerror(errno)); + + /* This is the child authenticating a new connection. */ + setproctitle("%s", "[session-auth]"); + + /* Executed child processes don't need these. */ + FD_CLOSEONEXEC(sock_out); + FD_CLOSEONEXEC(sock_in); + + ssh_signal(SIGPIPE, SIG_IGN); + ssh_signal(SIGALRM, SIG_DFL); + ssh_signal(SIGHUP, SIG_DFL); + ssh_signal(SIGTERM, SIG_DFL); + ssh_signal(SIGQUIT, SIG_DFL); + ssh_signal(SIGCHLD, SIG_DFL); + + /* Prepare the channels layer */ + channel_init_channels(ssh); + channel_set_af(ssh, options.address_family); + server_process_channel_timeouts(ssh); + server_process_permitopen(ssh); + + ssh_packet_set_nonblocking(ssh); + + /* allocate authentication context */ + authctxt = xcalloc(1, sizeof(*authctxt)); + ssh->authctxt = authctxt; + + /* XXX global for cleanup, access from other modules */ + the_authctxt = authctxt; + + /* Set default key authentication options */ + if ((auth_opts = sshauthopt_new_with_keys_defaults()) == NULL) + fatal("allocation failed"); + + /* prepare buffer to collect messages to display to user after login */ + if ((loginmsg = sshbuf_new()) == NULL) + fatal("sshbuf_new loginmsg failed"); + auth_debug_reset(); + +#ifdef GSSAPI + /* Cache supported mechanism OIDs for later use */ + ssh_gssapi_prepare_supported_oids(); +#endif + + privsep_child_demote(); + + /* perform the key exchange */ + /* authenticate user and start session */ + do_ssh2_kex(ssh); + do_authentication2(ssh); + + /* + * The unprivileged child now transfers the current keystate and exits. + */ + mm_send_keystate(ssh, pmonitor); + sshauthopt_free(auth_opts); + ssh_packet_clear_keys(ssh); + exit(0); +} + +int +sshd_hostkey_sign(struct ssh *ssh, struct sshkey *privkey, + struct sshkey *pubkey, u_char **signature, size_t *slenp, + const u_char *data, size_t dlen, const char *alg) +{ + if (privkey) { + if (mm_sshkey_sign(ssh, privkey, signature, slenp, + data, dlen, alg, options.sk_provider, NULL, + ssh->compat) < 0) + fatal_f("privkey sign failed"); + } else { + if (mm_sshkey_sign(ssh, pubkey, signature, slenp, + data, dlen, alg, options.sk_provider, NULL, + ssh->compat) < 0) + fatal_f("pubkey sign failed"); + } + return 0; +} + +/* SSH2 key exchange */ +static void +do_ssh2_kex(struct ssh *ssh) +{ + char *hkalgs = NULL, *myproposal[PROPOSAL_MAX]; + const char *compression = NULL; + struct kex *kex; + int r; + + if (options.rekey_limit || options.rekey_interval) + ssh_packet_set_rekey_limits(ssh, options.rekey_limit, + options.rekey_interval); + + if (options.compression == COMP_NONE) + compression = "none"; + hkalgs = list_hostkey_types(); + + kex_proposal_populate_entries(ssh, myproposal, options.kex_algorithms, + options.ciphers, options.macs, compression, hkalgs); + + free(hkalgs); + + if ((r = kex_exchange_identification(ssh, -1, + options.version_addendum)) != 0) + sshpkt_fatal(ssh, r, "banner exchange"); + mm_sshkey_setcompat(ssh); /* tell monitor */ + + if ((ssh->compat & SSH_BUG_NOREKEY)) + debug("client does not support rekeying"); + + /* start key exchange */ + if ((r = kex_setup(ssh, myproposal)) != 0) + fatal_r(r, "kex_setup"); + kex_set_server_sig_algs(ssh, options.pubkey_accepted_algos); + kex = ssh->kex; + +#ifdef WITH_OPENSSL + kex->kex[KEX_DH_GRP1_SHA1] = kex_gen_server; + kex->kex[KEX_DH_GRP14_SHA1] = kex_gen_server; + kex->kex[KEX_DH_GRP14_SHA256] = kex_gen_server; + kex->kex[KEX_DH_GRP16_SHA512] = kex_gen_server; + kex->kex[KEX_DH_GRP18_SHA512] = kex_gen_server; + kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; + kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; +# ifdef OPENSSL_HAS_ECC + kex->kex[KEX_ECDH_SHA2] = kex_gen_server; +# endif /* OPENSSL_HAS_ECC */ +#endif /* WITH_OPENSSL */ + kex->kex[KEX_C25519_SHA256] = kex_gen_server; + kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; + kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_server; + kex->load_host_public_key=&get_hostkey_public_by_type; + kex->load_host_private_key=&get_hostkey_private_by_type; + kex->host_key_index=&get_hostkey_index; + kex->sign = sshd_hostkey_sign; + + ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &kex->done); + kex_proposal_free_entries(myproposal); + +#ifdef DEBUG_KEXDH + /* send 1st encrypted/maced/compressed message */ + if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 || + (r = sshpkt_put_cstring(ssh, "markus")) != 0 || + (r = sshpkt_send(ssh)) != 0 || + (r = ssh_packet_write_wait(ssh)) != 0) + fatal_fr(r, "send test"); +#endif + debug("KEX done"); +} + +/* server specific fatal cleanup */ +void +cleanup_exit(int i) +{ + _exit(i); +} diff --git a/sshd-debug.sh b/sshd-debug.sh new file mode 100755 index 0000000..86a9b37 --- /dev/null +++ b/sshd-debug.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +# ssh-debug + +# A wrapper script around sshd to invoke when debugging to debug the +# work-in-progress versions of sshd-auth and sshd-session, instead +# of debugging the installed ones that probably don't have the change +# you are working on. +# +# Placed in the Public Domain. + +unset DIR SSHD SSHD_AUTH SSHD_SESSION + +fatal() { + echo >&2 $@ + exit 1 +} + +case "$0" in +/*) DIR="`dirname $0`" ;; +./sshd-debug.sh) DIR="`pwd`" ;; +*) echo "Need full path or working directory."; exit 1 ;; +esac + +for i in sshd/obj/sshd sshd/sshd sshd; do + if [ -f "${DIR}/$i" ] && [ -x "${DIR}/$i" ]; then + SSHD="${DIR}/$i" + fi +done +[ -z "${SSHD}" ] && fatal "Could not find sshd" + +for i in sshd-auth/obj/sshd-auth sshd-auth/sshd-auth sshd-auth; do + if [ -f "${DIR}/$i" ] && [ -x "${DIR}/$i" ]; then + SSHD_AUTH="${DIR}/$i" + fi +done +[ -z "${SSHD_AUTH}" ] && fatal "Could not find sshd-auth" + +for i in sshd-session/obj/sshd-session sshd-session/sshd-session sshd-session; do + if [ -f "${DIR}/$i" ] && [ -x "${DIR}/$i" ]; then + SSHD_SESSION="${DIR}/$i" + fi +done +[ -z "${SSHD_SESSION}" ] && fatal "Could not find sshd-session" + +echo >&2 Debugging ${SSHD} auth ${SSHD_AUTH} session ${SSHD_SESSION} + +# Append SshdSessionPath and SshdAuthPath pointing to the build directory. +# If you explicitly specify these in the command line, the first-match +# keyword semantics will override these. +exec "${SSHD}" $@ \ + -oSshdAuthPath="${SSHD_AUTH}" -oSshdSessionPath="${SSHD_SESSION}" diff --git a/sshd-session.c b/sshd-session.c index 4b79b9b..e9a488d 100644 --- a/sshd-session.c +++ b/sshd-session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd-session.c,v 1.9 2024/09/09 02:39:57 djm Exp $ */ +/* $OpenBSD: sshd-session.c,v 1.23 2026/03/11 09:10:59 dtucker Exp $ */ /* * SSH2 implementation: * Privilege Separation: @@ -31,23 +31,17 @@ #include #include -#include -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef HAVE_SYS_TIME_H -# include -#endif -#include "openbsd-compat/sys-tree.h" -#include "openbsd-compat/sys-queue.h" #include +#include +#include +#include +#include +#include #include #include #include -#ifdef HAVE_PATHS_H -# include -#endif +#include #include #include #include @@ -58,13 +52,6 @@ #include #include -#ifdef WITH_OPENSSL -#include -#include -#include -#include "openbsd-compat/openssl-compat.h" -#endif - #ifdef HAVE_SECUREWARE #include #include @@ -102,7 +89,6 @@ #include "ssh-gss.h" #endif #include "monitor_wrap.h" -#include "ssh-sandbox.h" #include "auth-options.h" #include "version.h" #include "ssherr.h" @@ -112,9 +98,13 @@ /* Re-exec fds */ #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) -#define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) -#define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 3) -#define REEXEC_MIN_FREE_FD (STDERR_FILENO + 4) +#define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 2) +#define REEXEC_MIN_FREE_FD (STDERR_FILENO + 3) + +/* Privsep fds */ +#define PRIVSEP_MONITOR_FD (STDERR_FILENO + 1) +#define PRIVSEP_LOG_FD (STDERR_FILENO + 2) +#define PRIVSEP_MIN_FREE_FD (STDERR_FILENO + 3) extern char *__progname; @@ -193,7 +183,17 @@ struct sshbuf *loginmsg; /* Prototypes for various functions defined later in this file. */ void destroy_sensitive_data(void); void demote_sensitive_data(void); -static void do_ssh2_kex(struct ssh *); + +/* XXX reduce to stub once postauth split */ +int +mm_is_monitor(void) +{ + /* + * m_pid is only set in the privileged part, and + * points to the unprivileged child. + */ + return (pmonitor && pmonitor->m_pid > 0); +} /* * Signal handler for the alarm after the login grace period has expired. @@ -262,81 +262,57 @@ demote_sensitive_data(void) } } -static void -reseed_prngs(void) +struct sshbuf * +pack_hostkeys(void) { - u_int32_t rnd[256]; - -#ifdef WITH_OPENSSL - RAND_poll(); -#endif - arc4random_stir(); /* noop on recent arc4random() implementations */ - arc4random_buf(rnd, sizeof(rnd)); /* let arc4random notice PID change */ - -#ifdef WITH_OPENSSL - RAND_seed(rnd, sizeof(rnd)); - /* give libcrypto a chance to notice the PID change */ - if ((RAND_bytes((u_char *)rnd, 1)) != 1) - fatal("%s: RAND_bytes failed", __func__); -#endif - - explicit_bzero(rnd, sizeof(rnd)); -} - -static void -privsep_preauth_child(void) -{ - gid_t gidset[1]; - - /* Enable challenge-response authentication for privilege separation */ - privsep_challenge_enable(); - -#ifdef GSSAPI - /* Cache supported mechanism OIDs for later use */ - ssh_gssapi_prepare_supported_oids(); -#endif - - reseed_prngs(); + struct sshbuf *keybuf = NULL, *hostkeys = NULL; + int r; + u_int i; - /* Demote the private keys to public keys. */ - demote_sensitive_data(); + if ((hostkeys = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); - /* Demote the child */ - if (privsep_chroot) { - /* Change our root directory */ - if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1) - fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR, - strerror(errno)); - if (chdir("/") == -1) - fatal("chdir(\"/\"): %s", strerror(errno)); - - /* Drop our privileges */ - debug3("privsep user:group %u:%u", (u_int)privsep_pw->pw_uid, - (u_int)privsep_pw->pw_gid); - gidset[0] = privsep_pw->pw_gid; - if (setgroups(1, gidset) == -1) - fatal("setgroups: %.100s", strerror(errno)); - permanently_set_uid(privsep_pw); + /* pack hostkeys into a string. Empty key slots get empty strings */ + for (i = 0; i < options.num_host_key_files; i++) { + /* public key */ + if (sensitive_data.host_pubkeys[i] != NULL) { + if ((r = sshkey_puts(sensitive_data.host_pubkeys[i], + hostkeys)) != 0) + fatal_fr(r, "compose hostkey public"); + } else { + if ((r = sshbuf_put_string(hostkeys, NULL, 0)) != 0) + fatal_fr(r, "compose hostkey empty public"); + } + /* cert */ + if (sensitive_data.host_certificates[i] != NULL) { + if ((r = sshkey_puts( + sensitive_data.host_certificates[i], + hostkeys)) != 0) + fatal_fr(r, "compose host cert"); + } else { + if ((r = sshbuf_put_string(hostkeys, NULL, 0)) != 0) + fatal_fr(r, "compose host cert empty"); + } } + + sshbuf_free(keybuf); + return hostkeys; } static int privsep_preauth(struct ssh *ssh) { - int status, r; + int r; pid_t pid; - struct ssh_sandbox *box = NULL; /* Set up unprivileged child process to deal with network data */ pmonitor = monitor_init(); /* Store a pointer to the kex for later rekeying */ pmonitor->m_pkex = &ssh->kex; - box = ssh_sandbox_init(pmonitor); - pid = fork(); - if (pid == -1) { + if ((pid = fork()) == -1) fatal("fork of unprivileged child failed"); - } else if (pid != 0) { + else if (pid != 0) { debug2("Network child is on pid %ld", (long)pid); pmonitor->m_pid = pid; @@ -347,43 +323,48 @@ privsep_preauth(struct ssh *ssh) have_agent = 0; } } - if (box != NULL) - ssh_sandbox_parent_preauth(box, pid); monitor_child_preauth(ssh, pmonitor); - - /* Wait for the child's exit status */ - while (waitpid(pid, &status, 0) == -1) { - if (errno == EINTR) - continue; - pmonitor->m_pid = -1; - fatal_f("waitpid: %s", strerror(errno)); - } privsep_is_preauth = 0; - pmonitor->m_pid = -1; - if (WIFEXITED(status)) { - if (WEXITSTATUS(status) != 0) - fatal_f("preauth child exited with status %d", - WEXITSTATUS(status)); - } else if (WIFSIGNALED(status)) - fatal_f("preauth child terminated by signal %d", - WTERMSIG(status)); - if (box != NULL) - ssh_sandbox_parent_finish(box); return 1; } else { /* child */ close(pmonitor->m_sendfd); close(pmonitor->m_log_recvfd); - /* Arrange for logging to be sent to the monitor */ - set_log_handler(mm_log_handler, pmonitor); - - privsep_preauth_child(); - setproctitle("%s", "[net]"); - if (box != NULL) - ssh_sandbox_child(box); + /* + * Arrange unpriv-preauth child process fds: + * 0, 1 network socket + * 2 optional stderr + * 3 reserved + * 4 monitor message socket + * 5 monitor logging socket + * + * We know that the monitor sockets will have fds > 4 because + * of the reserved fds in main() + */ - return 0; + if (ssh_packet_get_connection_in(ssh) != STDIN_FILENO && + dup2(ssh_packet_get_connection_in(ssh), STDIN_FILENO) == -1) + fatal("dup2 stdin failed: %s", strerror(errno)); + if (ssh_packet_get_connection_out(ssh) != STDOUT_FILENO && + dup2(ssh_packet_get_connection_out(ssh), + STDOUT_FILENO) == -1) + fatal("dup2 stdout failed: %s", strerror(errno)); + /* leave stderr as-is */ + log_redirect_stderr_to(NULL); /* dup can clobber log fd */ + if (pmonitor->m_recvfd != PRIVSEP_MONITOR_FD && + dup2(pmonitor->m_recvfd, PRIVSEP_MONITOR_FD) == -1) + fatal("dup2 monitor fd: %s", strerror(errno)); + if (pmonitor->m_log_sendfd != PRIVSEP_LOG_FD && + dup2(pmonitor->m_log_sendfd, PRIVSEP_LOG_FD) == -1) + fatal("dup2 log fd: %s", strerror(errno)); + closefrom(PRIVSEP_MIN_FREE_FD); + + saved_argv[0] = options.sshd_auth_path; + execv(options.sshd_auth_path, saved_argv); + + fatal_f("exec of %s failed: %s", + options.sshd_auth_path, strerror(errno)); } } @@ -396,7 +377,7 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) * Hack for systems that don't support FD passing: retain privileges * in the post-auth privsep process so it can allocate PTYs directly. * This is basically equivalent to what we did <= 9.7, which was to - * disable post-auth privsep entriely. + * disable post-auth privsep entirely. * Cygwin doesn't need to drop privs here although it doesn't support * fd passing, as AFAIK PTY allocation on this platform doesn't require * special privileges to begin with. @@ -445,79 +426,6 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) ssh_packet_set_authenticated(ssh); } -static void -append_hostkey_type(struct sshbuf *b, const char *s) -{ - int r; - - if (match_pattern_list(s, options.hostkeyalgorithms, 0) != 1) { - debug3_f("%s key not permitted by HostkeyAlgorithms", s); - return; - } - if ((r = sshbuf_putf(b, "%s%s", sshbuf_len(b) > 0 ? "," : "", s)) != 0) - fatal_fr(r, "sshbuf_putf"); -} - -static char * -list_hostkey_types(void) -{ - struct sshbuf *b; - struct sshkey *key; - char *ret; - u_int i; - - if ((b = sshbuf_new()) == NULL) - fatal_f("sshbuf_new failed"); - for (i = 0; i < options.num_host_key_files; i++) { - key = sensitive_data.host_keys[i]; - if (key == NULL) - key = sensitive_data.host_pubkeys[i]; - if (key == NULL) - continue; - switch (key->type) { - case KEY_RSA: - /* for RSA we also support SHA2 signatures */ - append_hostkey_type(b, "rsa-sha2-512"); - append_hostkey_type(b, "rsa-sha2-256"); - /* FALLTHROUGH */ - case KEY_DSA: - case KEY_ECDSA: - case KEY_ED25519: - case KEY_ECDSA_SK: - case KEY_ED25519_SK: - case KEY_XMSS: - append_hostkey_type(b, sshkey_ssh_name(key)); - break; - } - /* If the private key has a cert peer, then list that too */ - key = sensitive_data.host_certificates[i]; - if (key == NULL) - continue; - switch (key->type) { - case KEY_RSA_CERT: - /* for RSA we also support SHA2 signatures */ - append_hostkey_type(b, - "rsa-sha2-512-cert-v01@openssh.com"); - append_hostkey_type(b, - "rsa-sha2-256-cert-v01@openssh.com"); - /* FALLTHROUGH */ - case KEY_DSA_CERT: - case KEY_ECDSA_CERT: - case KEY_ED25519_CERT: - case KEY_ECDSA_SK_CERT: - case KEY_ED25519_SK_CERT: - case KEY_XMSS_CERT: - append_hostkey_type(b, sshkey_ssh_name(key)); - break; - } - } - if ((ret = sshbuf_dup_string(b)) == NULL) - fatal_f("sshbuf_dup_string failed"); - sshbuf_free(b); - debug_f("%s", ret); - return ret; -} - static struct sshkey * get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh) { @@ -527,12 +435,10 @@ get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh) for (i = 0; i < options.num_host_key_files; i++) { switch (type) { case KEY_RSA_CERT: - case KEY_DSA_CERT: case KEY_ECDSA_CERT: case KEY_ED25519_CERT: case KEY_ECDSA_SK_CERT: case KEY_ED25519_SK_CERT: - case KEY_XMSS_CERT: key = sensitive_data.host_certificates[i]; break; default: @@ -745,6 +651,8 @@ recv_rexec_state(int fd, struct sshbuf *conf, uint64_t *timing_secretp) if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); + + /* receive config */ if (ssh_msg_recv(fd, m) == -1) fatal_f("ssh_msg_recv failed"); if ((r = sshbuf_get_u8(m, &ver)) != 0) @@ -753,7 +661,6 @@ recv_rexec_state(int fd, struct sshbuf *conf, uint64_t *timing_secretp) fatal_f("rexec version mismatch"); if ((r = sshbuf_get_string(m, &cp, &len)) != 0 || /* XXX _direct */ (r = sshbuf_get_u64(m, timing_secretp)) != 0 || - (r = sshbuf_froms(m, &hostkeys)) != 0 || (r = sshbuf_get_stringb(m, inc)) != 0) fatal_fr(r, "parse config"); @@ -771,6 +678,13 @@ recv_rexec_state(int fd, struct sshbuf *conf, uint64_t *timing_secretp) TAILQ_INSERT_TAIL(&includes, item, entry); } + /* receive hostkeys */ + sshbuf_reset(m); + if (ssh_msg_recv(fd, m) == -1) + fatal_f("ssh_msg_recv failed"); + if ((r = sshbuf_get_u8(m, NULL)) != 0 || + (r = sshbuf_froms(m, &hostkeys)) != 0) + fatal_fr(r, "parse config"); parse_hostkeys(hostkeys); free(cp); @@ -871,12 +785,12 @@ main(int ac, char **av) struct ssh *ssh = NULL; extern char *optarg; extern int optind; - int r, opt, on = 1, remote_port; + int devnull, r, opt, on = 1, remote_port; int sock_in = -1, sock_out = -1, rexeced_flag = 0, have_key = 0; const char *remote_ip, *rdomain; char *line, *laddr, *logfile = NULL; u_int i; - u_int64_t ibytes, obytes; + uint64_t ibytes, obytes; mode_t new_umask; Authctxt *authctxt; struct connection_info *connection_info = NULL; @@ -1028,13 +942,21 @@ main(int ac, char **av) exit(1); } - debug("sshd version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION); - if (!rexeced_flag) fatal("sshd-session should not be executed directly"); closefrom(REEXEC_MIN_FREE_FD); + platform_pre_session_start(); + + /* Reserve fds we'll need later for reexec things */ + if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) + fatal("open %s: %s", _PATH_DEVNULL, strerror(errno)); + while (devnull < PRIVSEP_MIN_FREE_FD) { + if ((devnull = dup(devnull)) == -1) + fatal("dup %s: %s", _PATH_DEVNULL, strerror(errno)); + } + seed_rng(); /* If requested, redirect the logs to the specified logfile. */ @@ -1061,19 +983,22 @@ main(int ac, char **av) SYSLOG_FACILITY_AUTH : options.log_facility, log_stderr || !inetd_flag || debug_flag); - debug("sshd version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION); - /* Fetch our configuration */ if ((cfg = sshbuf_new()) == NULL) fatal("sshbuf_new config buf failed"); setproctitle("%s", "[rexeced]"); recv_rexec_state(REEXEC_CONFIG_PASS_FD, cfg, &timing_secret); - close(REEXEC_CONFIG_PASS_FD); parse_server_config(&options, "rexec", cfg, &includes, NULL, 1); /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); options.timing_secret = timing_secret; + /* Reinit logging in case config set Level, Facility or Verbose. */ + log_init(__progname, options.log_level, options.log_facility, + log_stderr || !inetd_flag || debug_flag); + + debug("sshd-session version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION); + /* Store privilege separation user for later use if required. */ privsep_chroot = (getuid() == 0 || geteuid() == 0); if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) { @@ -1087,15 +1012,19 @@ main(int ac, char **av) } endpwent(); - if (!debug_flag) { - startup_pipe = dup(REEXEC_STARTUP_PIPE_FD); - close(REEXEC_STARTUP_PIPE_FD); + if (!debug_flag && !inetd_flag) { + if ((startup_pipe = dup(REEXEC_CONFIG_PASS_FD)) == -1) + fatal("internal error: no startup pipe"); + /* * Signal parent that this child is at a point where * they can go away if they have a SIGHUP pending. */ (void)atomicio(vwrite, startup_pipe, "\0", 1); } + /* close the fd, but keep the slot reserved */ + if (dup2(devnull, REEXEC_CONFIG_PASS_FD) == -1) + fatal("dup2 devnull->config fd: %s", strerror(errno)); /* Check that options are sensible */ if (options.authorized_keys_command_user == NULL && @@ -1208,8 +1137,8 @@ main(int ac, char **av) setproctitle("%s", "[accepted]"); /* Executed child processes don't need these. */ - fcntl(sock_out, F_SETFD, FD_CLOEXEC); - fcntl(sock_in, F_SETFD, FD_CLOEXEC); + FD_CLOSEONEXEC(sock_out); + FD_CLOSEONEXEC(sock_in); /* We will not restart on SIGHUP since it no longer makes sense. */ ssh_signal(SIGALRM, SIG_DFL); @@ -1227,6 +1156,8 @@ main(int ac, char **av) fatal("Unable to create connection"); the_active_state = ssh; ssh_packet_set_server(ssh); + ssh_packet_set_qos(ssh, options.ip_qos_interactive, + options.ip_qos_bulk); check_ip_options(ssh); @@ -1289,10 +1220,6 @@ main(int ac, char **av) fatal("login grace time setitimer failed"); } - if ((r = kex_exchange_identification(ssh, -1, - options.version_addendum)) != 0) - sshpkt_fatal(ssh, r, "banner exchange"); - ssh_packet_set_nonblocking(ssh); /* allocate authentication context */ @@ -1311,22 +1238,11 @@ main(int ac, char **av) fatal("sshbuf_new loginmsg failed"); auth_debug_reset(); - if (privsep_preauth(ssh) == 1) - goto authenticated; + if (privsep_preauth(ssh) != 1) + fatal("privsep_preauth failed"); - /* perform the key exchange */ - /* authenticate user and start session */ - do_ssh2_kex(ssh); - do_authentication2(ssh); + /* Now user is authenticated */ - /* - * The unprivileged child now transfers the current keystate and exits. - */ - mm_send_keystate(ssh, pmonitor); - ssh_packet_clear_keys(ssh); - exit(0); - - authenticated: /* * Cancel the alarm we set to limit the time taken for * authentication. @@ -1423,74 +1339,10 @@ sshd_hostkey_sign(struct ssh *ssh, struct sshkey *privkey, return 0; } -/* SSH2 key exchange */ -static void -do_ssh2_kex(struct ssh *ssh) -{ - char *hkalgs = NULL, *myproposal[PROPOSAL_MAX]; - const char *compression = NULL; - struct kex *kex; - int r; - - if (options.rekey_limit || options.rekey_interval) - ssh_packet_set_rekey_limits(ssh, options.rekey_limit, - options.rekey_interval); - - if (options.compression == COMP_NONE) - compression = "none"; - hkalgs = list_hostkey_types(); - - kex_proposal_populate_entries(ssh, myproposal, options.kex_algorithms, - options.ciphers, options.macs, compression, hkalgs); - - free(hkalgs); - - /* start key exchange */ - if ((r = kex_setup(ssh, myproposal)) != 0) - fatal_r(r, "kex_setup"); - kex_set_server_sig_algs(ssh, options.pubkey_accepted_algos); - kex = ssh->kex; - -#ifdef WITH_OPENSSL - kex->kex[KEX_DH_GRP1_SHA1] = kex_gen_server; - kex->kex[KEX_DH_GRP14_SHA1] = kex_gen_server; - kex->kex[KEX_DH_GRP14_SHA256] = kex_gen_server; - kex->kex[KEX_DH_GRP16_SHA512] = kex_gen_server; - kex->kex[KEX_DH_GRP18_SHA512] = kex_gen_server; - kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; - kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; - #ifdef OPENSSL_HAS_ECC - kex->kex[KEX_ECDH_SHA2] = kex_gen_server; - #endif -#endif - kex->kex[KEX_C25519_SHA256] = kex_gen_server; - kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; - kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_server; - kex->load_host_public_key=&get_hostkey_public_by_type; - kex->load_host_private_key=&get_hostkey_private_by_type; - kex->host_key_index=&get_hostkey_index; - kex->sign = sshd_hostkey_sign; - - ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &kex->done); - kex_proposal_free_entries(myproposal); - -#ifdef DEBUG_KEXDH - /* send 1st encrypted/maced/compressed message */ - if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 || - (r = sshpkt_put_cstring(ssh, "markus")) != 0 || - (r = sshpkt_send(ssh)) != 0 || - (r = ssh_packet_write_wait(ssh)) != 0) - fatal_fr(r, "send test"); -#endif - debug("KEX done"); -} - /* server specific fatal cleanup */ void cleanup_exit(int i) { - extern int auth_attempted; /* monitor.c */ - if (the_active_state != NULL && the_authctxt != NULL) { do_cleanup(the_active_state, the_authctxt); if (privsep_is_preauth && @@ -1509,7 +1361,9 @@ cleanup_exit(int i) audit_event(the_active_state, SSH_CONNECTION_ABANDON); #endif /* Override default fatal exit value when auth was attempted */ - if (i == 255 && auth_attempted) + if (i == 255 && monitor_auth_attempted()) _exit(EXIT_AUTH_ATTEMPTED); + if (i == 255 && monitor_invalid_user()) + _exit(EXIT_INVALID_USER); _exit(i); } diff --git a/sshd.0 b/sshd.0 index 23e28be..890adcb 100644 --- a/sshd.0 +++ b/sshd.0 @@ -306,7 +306,7 @@ AUTHORIZED_KEYS FILE FORMAT The command originally supplied by the client is available in the SSH_ORIGINAL_COMMAND environment variable. Note that this option applies to shell, command or subsystem execution. Also note that - this command may be superseded by a sshd_config(5) ForceCommand + this command may be superseded by an sshd_config(5) ForceCommand directive. If a command is specified and a forced-command is embedded in a @@ -684,4 +684,4 @@ AUTHORS versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support for privilege separation. -OpenBSD 7.6 September 15, 2024 OpenBSD 7.6 +OpenBSD 7.8 October 4, 2025 SSHD(8) diff --git a/sshd.8 b/sshd.8 index 08ebf53..7fbca77 100644 --- a/sshd.8 +++ b/sshd.8 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd.8,v 1.327 2024/09/15 01:19:56 djm Exp $ -.Dd $Mdocdate: September 15 2024 $ +.\" $OpenBSD: sshd.8,v 1.328 2025/10/04 21:41:35 naddy Exp $ +.Dd $Mdocdate: October 4 2025 $ .Dt SSHD 8 .Os .Sh NAME @@ -530,7 +530,7 @@ The command originally supplied by the client is available in the .Ev SSH_ORIGINAL_COMMAND environment variable. Note that this option applies to shell, command or subsystem execution. -Also note that this command may be superseded by a +Also note that this command may be superseded by an .Xr sshd_config 5 .Cm ForceCommand directive. diff --git a/sshd.c b/sshd.c index df76dc7..74d25fc 100644 --- a/sshd.c +++ b/sshd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd.c,v 1.612 2024/09/15 01:11:26 djm Exp $ */ +/* $OpenBSD: sshd.c,v 1.626 2026/02/09 21:21:39 dtucker Exp $ */ /* * Copyright (c) 2000, 2001, 2002 Markus Friedl. All rights reserved. * Copyright (c) 2002 Niels Provos. All rights reserved. @@ -29,41 +29,28 @@ #include #include #include -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef HAVE_SYS_TIME_H -# include -#endif -#include "openbsd-compat/sys-tree.h" -#include "openbsd-compat/sys-queue.h" +#include +#include +#include #include +#include #include #include #include -#ifdef HAVE_PATHS_H #include -#endif #include -#ifdef HAVE_POLL_H #include -#endif #include #include #include +#include #include #include #include #include #include -#ifdef WITH_OPENSSL -#include -#include -#include "openbsd-compat/openssl-compat.h" -#endif - #ifdef HAVE_SECUREWARE #include #include @@ -91,12 +78,16 @@ #include "sk-api.h" #include "addr.h" #include "srclimit.h" +#include "atomicio.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif +#include "monitor_wrap.h" /* Re-exec fds */ #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) -#define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) -#define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 3) -#define REEXEC_MIN_FREE_FD (STDERR_FILENO + 4) +#define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 2) +#define REEXEC_MIN_FREE_FD (STDERR_FILENO + 3) extern char *__progname; @@ -181,13 +172,15 @@ struct early_child { struct xaddr addr; int have_addr; int status, have_status; + struct sshbuf *config; + struct sshbuf *keys; }; static struct early_child *children; static int children_active; -static int startup_pipe = -1; /* in child */ /* sshd_config buffer */ struct sshbuf *cfg; +struct sshbuf *config; /* packed */ /* Included files from the configuration file */ struct include_list includes = TAILQ_HEAD_INITIALIZER(includes); @@ -238,7 +231,10 @@ child_register(int pipefd, int sockfd) struct sockaddr *sa = (struct sockaddr *)&addr; for (i = 0; i < options.max_startups; i++) { - if (children[i].pipefd != -1 || children[i].pid > 0) + if (children[i].pipefd != -1 || + children[i].config != NULL || + children[i].keys != NULL || + children[i].pid > 0) continue; child = &(children[i]); break; @@ -249,6 +245,8 @@ child_register(int pipefd, int sockfd) } child->pipefd = pipefd; child->early = 1; + if ((child->config = sshbuf_fromb(config)) == NULL) + fatal_f("sshbuf_fromb failed"); /* record peer address, if available */ if (getpeername(sockfd, sa, &addrlen) == 0 && addr_sa_to_xaddr(sa, addrlen, &child->addr) == 0) @@ -280,8 +278,12 @@ child_finish(struct early_child *child) { if (children_active == 0) fatal_f("internal error: children_active underflow"); - if (child->pipefd != -1) + if (child->pipefd != -1) { + srclimit_done(child->pipefd); close(child->pipefd); + } + sshbuf_free(child->config); + sshbuf_free(child->keys); free(child->id); memset(child, '\0', sizeof(*child)); child->pipefd = -1; @@ -300,6 +302,7 @@ child_close(struct early_child *child, int force_final, int quiet) if (!quiet) debug_f("enter%s", force_final ? " (forcing)" : ""); if (child->pipefd != -1) { + srclimit_done(child->pipefd); close(child->pipefd); child->pipefd = -1; } @@ -335,6 +338,16 @@ child_reap(struct early_child *child) { LogLevel level = SYSLOG_LEVEL_DEBUG1; int was_crash, penalty_type = SRCLIMIT_PENALTY_NONE; + const char *child_status; + + if (child->config) + child_status = " (sending config)"; + else if (child->keys) + child_status = " (sending keys)"; + else if (child->early) + child_status = " (early)"; + else + child_status = ""; /* Log exit information */ if (WIFSIGNALED(child->status)) { @@ -346,54 +359,56 @@ child_reap(struct early_child *child) level = SYSLOG_LEVEL_ERROR; do_log2(level, "session process %ld for %s killed by " "signal %d%s", (long)child->pid, child->id, - WTERMSIG(child->status), child->early ? " (early)" : ""); + WTERMSIG(child->status), child_status); if (was_crash) penalty_type = SRCLIMIT_PENALTY_CRASH; } else if (!WIFEXITED(child->status)) { penalty_type = SRCLIMIT_PENALTY_CRASH; error("session process %ld for %s terminated abnormally, " "status=0x%x%s", (long)child->pid, child->id, child->status, - child->early ? " (early)" : ""); + child_status); } else { /* Normal exit. We care about the status */ switch (WEXITSTATUS(child->status)) { case 0: debug3_f("preauth child %ld for %s completed " - "normally %s", (long)child->pid, child->id, - child->early ? " (early)" : ""); + "normally%s", (long)child->pid, child->id, + child_status); break; case EXIT_LOGIN_GRACE: penalty_type = SRCLIMIT_PENALTY_GRACE_EXCEEDED; logit("Timeout before authentication for %s, " "pid = %ld%s", child->id, (long)child->pid, - child->early ? " (early)" : ""); + child_status); break; case EXIT_CHILD_CRASH: penalty_type = SRCLIMIT_PENALTY_CRASH; logit("Session process %ld unpriv child crash for %s%s", - (long)child->pid, child->id, - child->early ? " (early)" : ""); + (long)child->pid, child->id, child_status); break; case EXIT_AUTH_ATTEMPTED: penalty_type = SRCLIMIT_PENALTY_AUTHFAIL; debug_f("preauth child %ld for %s exited " - "after unsuccessful auth attempt %s", - (long)child->pid, child->id, - child->early ? " (early)" : ""); + "after unsuccessful auth attempt%s", + (long)child->pid, child->id, child_status); + break; + case EXIT_INVALID_USER: + penalty_type = SRCLIMIT_PENALTY_INVALIDUSER; + debug_f("preauth child %ld for %s exited " + "after auth attempt by invalid user%s", + (long)child->pid, child->id, child_status); break; case EXIT_CONFIG_REFUSED: penalty_type = SRCLIMIT_PENALTY_REFUSECONNECTION; debug_f("preauth child %ld for %s prohibited by" - "RefuseConnection %s", - (long)child->pid, child->id, - child->early ? " (early)" : ""); + "RefuseConnection%s", + (long)child->pid, child->id, child_status); break; default: penalty_type = SRCLIMIT_PENALTY_NOAUTH; debug_f("preauth child %ld for %s exited " "with status %d%s", (long)child->pid, child->id, - WEXITSTATUS(child->status), - child->early ? " (early)" : ""); + WEXITSTATUS(child->status), child_status); break; } } @@ -456,6 +471,7 @@ static void show_info(void) { int i; + const char *child_status; /* XXX print listening sockets here too */ if (children == NULL) @@ -464,9 +480,16 @@ show_info(void) for (i = 0; i < options.max_startups; i++) { if (children[i].pipefd == -1 && children[i].pid <= 0) continue; + if (children[i].config) + child_status = " (sending config)"; + else if (children[i].keys) + child_status = " (sending keys)"; + else if (children[i].early) + child_status = " (early)"; + else + child_status = ""; logit("child %d: fd=%d pid=%ld %s%s", i, children[i].pipefd, - (long)children[i].pid, children[i].id, - children[i].early ? " (early)" : ""); + (long)children[i].pid, children[i].id, child_status); } srclimit_penalty_info(); } @@ -564,59 +587,51 @@ should_drop_connection(int startups) static int drop_connection(int sock, int startups, int notify_pipe) { + static struct log_ratelimit_ctx ratelimit_maxstartups; + static struct log_ratelimit_ctx ratelimit_penalty; + static int init_done; char *laddr, *raddr; - const char *reason = NULL, msg[] = "Not allowed at this time\r\n"; - static time_t last_drop, first_drop; - static u_int ndropped; - LogLevel drop_level = SYSLOG_LEVEL_VERBOSE; - time_t now; - - if (!srclimit_penalty_check_allow(sock, &reason)) { - drop_level = SYSLOG_LEVEL_INFO; - goto handle; + const char *reason = NULL, *subreason = NULL; + const char msg[] = "Not allowed at this time\r\n"; + struct log_ratelimit_ctx *rl = NULL; + int ratelimited; + u_int ndropped; + + if (!init_done) { + init_done = 1; + log_ratelimit_init(&ratelimit_maxstartups, 4, 60, 20, 5*60); + log_ratelimit_init(&ratelimit_penalty, 8, 60, 30, 2*60); } - now = monotime(); - if (!should_drop_connection(startups) && - srclimit_check_allow(sock, notify_pipe) == 1) { - if (last_drop != 0 && - startups < options.max_startups_begin - 1) { - /* XXX maybe need better hysteresis here */ - logit("exited MaxStartups throttling after %s, " - "%u connections dropped", - fmt_timeframe(now - first_drop), ndropped); - last_drop = 0; - } - return 0; - } - -#define SSHD_MAXSTARTUPS_LOG_INTERVAL (5 * 60) - if (last_drop == 0) { - error("beginning MaxStartups throttling"); - drop_level = SYSLOG_LEVEL_INFO; - first_drop = now; - ndropped = 0; - } else if (last_drop + SSHD_MAXSTARTUPS_LOG_INTERVAL < now) { - /* Periodic logs */ - error("in MaxStartups throttling for %s, " - "%u connections dropped", - fmt_timeframe(now - first_drop), ndropped + 1); - drop_level = SYSLOG_LEVEL_INFO; + /* PerSourcePenalties */ + if (!srclimit_penalty_check_allow(sock, &subreason)) { + reason = "PerSourcePenalties"; + rl = &ratelimit_penalty; + } else { + /* MaxStartups */ + if (!should_drop_connection(startups) && + srclimit_check_allow(sock, notify_pipe) == 1) + return 0; + reason = "Maxstartups"; + rl = &ratelimit_maxstartups; } - last_drop = now; - ndropped++; - reason = "past Maxstartups"; - handle: laddr = get_local_ipaddr(sock); raddr = get_peer_ipaddr(sock); - do_log2(drop_level, "drop connection #%d from [%s]:%d on [%s]:%d %s", + ratelimited = log_ratelimit(rl, time(NULL), NULL, &ndropped); + do_log2(ratelimited ? SYSLOG_LEVEL_DEBUG3 : SYSLOG_LEVEL_INFO, + "drop connection #%d from [%s]:%d on [%s]:%d %s", startups, raddr, get_peer_port(sock), laddr, get_local_port(sock), - reason); + subreason != NULL ? subreason : reason); free(laddr); free(raddr); + if (ndropped != 0) { + logit("%s logging rate-limited: additional %u connections " + "dropped", reason, ndropped); + } + /* best-effort notification to client */ (void)write(sock, msg, sizeof(msg) - 1); return 1; @@ -637,11 +652,13 @@ usage(void) static struct sshbuf * pack_hostkeys(void) { - struct sshbuf *keybuf = NULL, *hostkeys = NULL; + struct sshbuf *m = NULL, *keybuf = NULL, *hostkeys = NULL; int r; u_int i; + size_t len; - if ((keybuf = sshbuf_new()) == NULL || + if ((m = sshbuf_new()) == NULL || + (keybuf = sshbuf_new()) == NULL || (hostkeys = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); @@ -676,19 +693,28 @@ pack_hostkeys(void) } } + if ((r = sshbuf_put_u32(m, 0)) != 0 || + (r = sshbuf_put_u8(m, 0)) != 0 || + (r = sshbuf_put_stringb(m, hostkeys)) != 0) + fatal_fr(r, "compose message"); + if ((len = sshbuf_len(m)) < 5 || len > 0xffffffff) + fatal_f("bad length %zu", len); + POKE_U32(sshbuf_mutable_ptr(m), len - 4); + sshbuf_free(keybuf); - return hostkeys; + sshbuf_free(hostkeys); + return m; } -static void -send_rexec_state(int fd, struct sshbuf *conf) +static struct sshbuf * +pack_config(struct sshbuf *conf) { - struct sshbuf *m = NULL, *inc = NULL, *hostkeys = NULL; + struct sshbuf *m = NULL, *inc = NULL; struct include_item *item = NULL; - int r, sz; + size_t len; + int r; - debug3_f("entering fd = %d config len %zu", fd, - sshbuf_len(conf)); + debug3_f("d config len %zu", sshbuf_len(conf)); if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL) @@ -702,42 +728,76 @@ send_rexec_state(int fd, struct sshbuf *conf) fatal_fr(r, "compose includes"); } - hostkeys = pack_hostkeys(); - - /* - * Protocol from reexec master to child: - * string configuration - * uint64 timing_secret - * string host_keys[] { - * string private_key - * string public_key - * string certificate - * } - * string included_files[] { - * string selector - * string filename - * string contents - * } - */ - if ((r = sshbuf_put_stringb(m, conf)) != 0 || + if ((r = sshbuf_put_u32(m, 0)) != 0 || + (r = sshbuf_put_u8(m, 0)) != 0 || + (r = sshbuf_put_stringb(m, conf)) != 0 || (r = sshbuf_put_u64(m, options.timing_secret)) != 0 || - (r = sshbuf_put_stringb(m, hostkeys)) != 0 || (r = sshbuf_put_stringb(m, inc)) != 0) fatal_fr(r, "compose config"); - /* We need to fit the entire message inside the socket send buffer */ - sz = ROUNDUP(sshbuf_len(m) + 5, 16*1024); - if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sz, sizeof sz) == -1) - fatal_f("setsockopt SO_SNDBUF: %s", strerror(errno)); - - if (ssh_msg_send(fd, 0, m) == -1) - error_f("ssh_msg_send failed"); + if ((len = sshbuf_len(m)) < 5 || len > 0xffffffff) + fatal_f("bad length %zu", len); + POKE_U32(sshbuf_mutable_ptr(m), len - 4); - sshbuf_free(m); sshbuf_free(inc); - sshbuf_free(hostkeys); debug3_f("done"); + return m; +} + +/* + * Protocol from reexec master to child: + * uint32 size + * uint8 type (ignored) + * string configuration + * uint64 timing_secret + * string included_files[] { + * string selector + * string filename + * string contents + * } + * Second message + * uint32 size + * uint8 type (ignored) + * string host_keys[] { + * string private_key + * string public_key + * string certificate + * } + */ +/* + * This function is used only if inet_flag or debug_flag is set, + * otherwise the data is sent from the main poll loop. + * It sends the config from a child process back to the parent. + * The parent will read the config after exec. + */ +static void +send_rexec_state(int fd) +{ + struct sshbuf *keys; + u_int mlen; + pid_t pid; + + if ((pid = fork()) == -1) + fatal_f("fork failed: %s", strerror(errno)); + if (pid != 0) + return; + + debug3_f("entering fd = %d config len %zu", fd, + sshbuf_len(config)); + + mlen = sshbuf_len(config); + if (atomicio(vwrite, fd, sshbuf_mutable_ptr(config), mlen) != mlen) + error_f("write: %s", strerror(errno)); + + keys = pack_hostkeys(); + mlen = sshbuf_len(keys); + if (atomicio(vwrite, fd, sshbuf_mutable_ptr(keys), mlen) != mlen) + error_f("write: %s", strerror(errno)); + + sshbuf_free(keys); + debug3_f("done"); + exit(0); } /* @@ -852,14 +912,16 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, int log_stderr) { struct pollfd *pfd = NULL; - int i, ret, npfd; + int i, ret, npfd, r; int oactive = -1, listening = 0, lameduck = 0; - int startup_p[2] = { -1 , -1 }, *startup_pollfd; + int *startup_pollfd; + ssize_t len; + const u_char *ptr; char c = 0; struct sockaddr_storage from; struct early_child *child; + struct sshbuf *buf; socklen_t fromlen; - u_char rnd[256]; sigset_t nsigset, osigset; /* pipes connected to unauthenticated child sshd processes */ @@ -935,6 +997,9 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, if (children[i].pipefd != -1) { pfd[npfd].fd = children[i].pipefd; pfd[npfd].events = POLLIN; + if (children[i].config != NULL || + children[i].keys != NULL) + pfd[npfd].events |= POLLOUT; startup_pollfd[i] = npfd++; } } @@ -950,6 +1015,49 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, if (ret == -1) continue; + for (i = 0; i < options.max_startups; i++) { + if (children[i].pipefd == -1 || + startup_pollfd[i] == -1 || + !(pfd[startup_pollfd[i]].revents & POLLOUT)) + continue; + if (children[i].config) + buf = children[i].config; + else if (children[i].keys) + buf = children[i].keys; + else { + error_f("no buffer to send"); + continue; + } + ptr = sshbuf_ptr(buf); + len = sshbuf_len(buf); + ret = write(children[i].pipefd, ptr, len); + if (ret == -1 && (errno == EINTR || errno == EAGAIN)) + continue; + if (ret <= 0) { + if (children[i].early) + listening--; + child_close(&(children[i]), 0, 0); + continue; + } + if (ret == len) { + /* finished sending buffer */ + sshbuf_free(buf); + if (children[i].config == buf) { + /* sent config, now send keys */ + children[i].config = NULL; + children[i].keys = pack_hostkeys(); + } else if (children[i].keys == buf) { + /* sent both config and keys */ + children[i].keys = NULL; + } else { + fatal("config buf not set"); + } + + } else { + if ((r = sshbuf_consume(buf, ret)) != 0) + fatal_fr(r, "config buf inconsistent"); + } + } for (i = 0; i < options.max_startups; i++) { if (children[i].pipefd == -1 || startup_pollfd[i] == -1 || @@ -966,13 +1074,20 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, } /* FALLTHROUGH */ case 0: - /* child exited preauth */ + /* child closed pipe */ if (children[i].early) listening--; - srclimit_done(children[i].pipefd); + debug3_f("child %lu for %s closed pipe", + (long)children[i].pid, children[i].id); child_close(&(children[i]), 0, 0); break; case 1: + if (children[i].config) { + error_f("startup pipe %d (fd=%d)" + " early read", + i, children[i].pipefd); + goto problem_child; + } if (children[i].early && c == '\0') { /* child has finished preliminaries */ listening--; @@ -991,6 +1106,12 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, "child %ld for %s in state %d", (int)c, (long)children[i].pid, children[i].id, children[i].early); + problem_child: + if (children[i].early) + listening--; + if (children[i].pid > 0) + kill(children[i].pid, SIGTERM); + child_close(&(children[i]), 0, 0); } break; } @@ -1014,26 +1135,18 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, close(*newsock); continue; } - if (pipe(startup_p) == -1) { - error_f("pipe(startup_p): %s", strerror(errno)); - close(*newsock); - continue; - } - if (drop_connection(*newsock, - children_active, startup_p[0])) { - close(*newsock); - close(startup_p[0]); - close(startup_p[1]); - continue; - } - if (socketpair(AF_UNIX, SOCK_STREAM, 0, config_s) == -1) { error("reexec socketpair: %s", strerror(errno)); close(*newsock); - close(startup_p[0]); - close(startup_p[1]); + continue; + } + if (drop_connection(*newsock, + children_active, config_s[0])) { + close(*newsock); + close(config_s[0]); + close(config_s[1]); continue; } @@ -1051,12 +1164,10 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, close_listen_socks(); *sock_in = *newsock; *sock_out = *newsock; - close(startup_p[0]); - close(startup_p[1]); - startup_pipe = -1; - send_rexec_state(config_s[0], cfg); + send_rexec_state(config_s[0]); close(config_s[0]); free(pfd); + free(startup_pollfd); return; } @@ -1066,8 +1177,9 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, * parent continues listening. */ platform_pre_fork(); + set_nonblock(config_s[0]); listening++; - child = child_register(startup_p[0], *newsock); + child = child_register(config_s[0], *newsock); if ((child->pid = fork()) == 0) { /* * Child. Close the listening and @@ -1078,7 +1190,6 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, * the connection. */ platform_post_fork_child(); - startup_pipe = startup_p[1]; close_startup_pipes(); close_listen_socks(); *sock_in = *newsock; @@ -1089,6 +1200,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, log_stderr); close(config_s[0]); free(pfd); + free(startup_pollfd); return; } @@ -1099,25 +1211,14 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, else debug("Forked child %ld.", (long)child->pid); - close(startup_p[1]); - close(config_s[1]); - send_rexec_state(config_s[0], cfg); - close(config_s[0]); close(*newsock); /* * Ensure that our random state differs * from that of the child */ - arc4random_stir(); - arc4random_buf(rnd, sizeof(rnd)); -#ifdef WITH_OPENSSL - RAND_seed(rnd, sizeof(rnd)); - if ((RAND_bytes((u_char *)rnd, 1)) != 1) - fatal("%s: RAND_bytes failed", __func__); -#endif - explicit_bzero(rnd, sizeof(rnd)); + reseed_prngs(); } } } @@ -1193,13 +1294,14 @@ main(int ac, char **av) int sock_in = -1, sock_out = -1, newsock = -1, rexec_argc = 0; int devnull, config_s[2] = { -1 , -1 }, have_connection_info = 0; int need_chroot = 1; - char *fp, *line, *logfile = NULL, **rexec_argv = NULL; + char *args, *fp, *line, *logfile = NULL, **rexec_argv = NULL; struct stat sb; u_int i, j; mode_t new_umask; struct sshkey *key; struct sshkey *pubkey; struct connection_info connection_info; + struct utsname utsname; sigset_t sigmask; memset(&connection_info, 0, sizeof(connection_info)); @@ -1235,6 +1337,7 @@ main(int ac, char **av) initialize_server_options(&options); /* Parse command-line arguments. */ + args = argv_assemble(ac, av); /* logged later */ while ((opt = getopt(ac, av, "C:E:b:c:f:g:h:k:o:p:u:46DGQRTdeiqrtV")) != -1) { switch (opt) { @@ -1404,6 +1507,16 @@ main(int ac, char **av) fatal("Config test connection parameter (-C) provided without " "test mode (-T)"); + debug("sshd version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION); + if (uname(&utsname) != 0) { + memset(&utsname, 0, sizeof(utsname)); + strlcpy(utsname.sysname, "UNKNOWN", sizeof(utsname.sysname)); + } + debug3("Running on %s %s %s %s", utsname.sysname, utsname.release, + utsname.version, utsname.machine); + debug3("Started with: %s", args); + free(args); + /* Fetch our configuration */ if ((cfg = sshbuf_new()) == NULL) fatal("sshbuf_new config failed"); @@ -1451,8 +1564,6 @@ main(int ac, char **av) exit(1); } - debug("sshd version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION); - if (do_dump_cfg) print_config(&connection_info); @@ -1540,12 +1651,10 @@ main(int ac, char **av) switch (keytype) { case KEY_RSA: - case KEY_DSA: case KEY_ECDSA: case KEY_ED25519: case KEY_ECDSA_SK: case KEY_ED25519_SK: - case KEY_XMSS: if (have_agent || key != NULL) sensitive_data.have_ssh2_key = 1; break; @@ -1634,6 +1743,12 @@ main(int ac, char **av) if (test_flag > 1) print_config(&connection_info); + config = pack_config(cfg); + if (sshbuf_len(config) > MONITOR_MAX_CFGLEN) { + fatal("Configuration file is too large (have %zu, max %d)", + sshbuf_len(config), MONITOR_MAX_CFGLEN); + } + /* Configuration looks good, so exit if in test mode. */ if (test_flag) exit(0); @@ -1664,6 +1779,13 @@ main(int ac, char **av) fatal("%s does not exist or is not executable", rexec_argv[0]); debug3("using %s for re-exec", rexec_argv[0]); + /* Ensure that the privsep binary exists now too. */ + if (stat(options.sshd_auth_path, &sb) != 0 || + !(sb.st_mode & (S_IXOTH|S_IXUSR))) { + fatal("%s does not exist or is not executable", + options.sshd_auth_path); + } + listener_proctitle = prepare_proctitle(ac, av); /* Ensure that umask disallows at least group and world write */ @@ -1709,7 +1831,7 @@ main(int ac, char **av) /* Send configuration to ancestor sshd-session process */ if (socketpair(AF_UNIX, SOCK_STREAM, 0, config_s) == -1) fatal("socketpair: %s", strerror(errno)); - send_rexec_state(config_s[0], cfg); + send_rexec_state(config_s[0]); close(config_s[0]); } else { platform_pre_listen(); @@ -1757,8 +1879,8 @@ main(int ac, char **av) if (!debug_flag && !inetd_flag && setsid() == -1) error("setsid: %.100s", strerror(errno)); - debug("rexec start in %d out %d newsock %d pipe %d sock %d/%d", - sock_in, sock_out, newsock, startup_pipe, config_s[0], config_s[1]); + debug("rexec start in %d out %d newsock %d config_s %d/%d", + sock_in, sock_out, newsock, config_s[0], config_s[1]); if (!inetd_flag) { if (dup2(newsock, STDIN_FILENO) == -1) fatal("dup2 stdin: %s", strerror(errno)); @@ -1772,13 +1894,6 @@ main(int ac, char **av) fatal("dup2 config_s: %s", strerror(errno)); close(config_s[1]); } - if (startup_pipe == -1) - close(REEXEC_STARTUP_PIPE_FD); - else if (startup_pipe != REEXEC_STARTUP_PIPE_FD) { - if (dup2(startup_pipe, REEXEC_STARTUP_PIPE_FD) == -1) - fatal("dup2 startup_p: %s", strerror(errno)); - close(startup_pipe); - } log_redirect_stderr_to(NULL); closefrom(REEXEC_MIN_FREE_FD); diff --git a/sshd_config b/sshd_config index 36894ac..0f4a3a7 100644 --- a/sshd_config +++ b/sshd_config @@ -1,4 +1,4 @@ -# $OpenBSD: sshd_config,v 1.104 2021/07/02 05:11:21 dtucker Exp $ +# $OpenBSD: sshd_config,v 1.105 2024/12/03 14:12:47 dtucker Exp $ # This is the sshd server system-wide configuration file. See # sshd_config(5) for more information. @@ -53,11 +53,13 @@ AuthorizedKeysFile .ssh/authorized_keys # Don't read the user's ~/.rhosts and ~/.shosts files #IgnoreRhosts yes -# To disable tunneled clear text passwords, change to no here! +# To disable tunneled clear text passwords, change to "no" here! #PasswordAuthentication yes #PermitEmptyPasswords no -# Change to no to disable s/key passwords +# Change to "no" to disable keyboard-interactive authentication. Depending on +# the system's configuration, this may involve passwords, challenge-response, +# one-time passwords or some combination of these and other methods. #KbdInteractiveAuthentication yes # Kerberos options diff --git a/sshd_config.0 b/sshd_config.0 index a9d8b79..770ec74 100644 --- a/sshd_config.0 +++ b/sshd_config.0 @@ -45,8 +45,8 @@ DESCRIPTION users whose primary group or supplementary group list matches one of the patterns. Only group names are valid; a numerical group ID is not recognized. By default, login is allowed for all - groups. The allow/deny groups directives are processed in the - following order: DenyGroups, AllowGroups. + groups. AllowGroups is not consulted for groups matched by + DenyGroups. See PATTERNS in ssh_config(5) for more information on patterns. This keyword may appear multiple times in sshd_config with each @@ -80,8 +80,8 @@ DESCRIPTION USER@HOST then USER and HOST are separately checked, restricting logins to particular users from particular hosts. HOST criteria may additionally contain addresses to match in CIDR - address/masklen format. The allow/deny users directives are - processed in the following order: DenyUsers, AllowUsers. + address/masklen format. AllowUsers is not consulted for users + matched by DenyUsers. See PATTERNS in ssh_config(5) for more information on patterns. This keyword may appear multiple times in sshd_config with each @@ -137,7 +137,8 @@ DESCRIPTION of authorized_keys output (see AUTHORIZED_KEYS in sshd(8)). AuthorizedKeysCommand is tried after the usual AuthorizedKeysFile files and will not be executed if a matching key is found there. - By default, no AuthorizedKeysCommand is run. + By default, no AuthorizedKeysCommand is run. This command is + only executed for valid users. AuthorizedKeysCommandUser Specifies the user under whose account the AuthorizedKeysCommand @@ -150,12 +151,14 @@ DESCRIPTION Specifies the file that contains the public keys used for user authentication. The format is described in the AUTHORIZED_KEYS FILE FORMAT section of sshd(8). Arguments to AuthorizedKeysFile - accept the tokens described in the TOKENS section. After - expansion, AuthorizedKeysFile is taken to be an absolute path or - one relative to the user's home directory. Multiple files may be - listed, separated by whitespace. Alternately this option may be - set to none to skip checking for user keys in files. The default - is ".ssh/authorized_keys .ssh/authorized_keys2". + may include wildcards and accept the tokens described in the + TOKENS section. After expansion, AuthorizedKeysFile is taken to + be an absolute path or one relative to the user's home directory. + Multiple files may be listed, separated by whitespace. + Alternately this option may be set to none to skip checking for + user keys in files. The default is ".ssh/authorized_keys + .ssh/authorized_keys2". These files are only checked for valid + users. AuthorizedPrincipalsCommand Specifies a program to be used to generate the list of allowed @@ -171,7 +174,8 @@ DESCRIPTION AuthorizedPrincipalsCommand or AuthorizedPrincipalsFile is specified, then certificates offered by the client for authentication must contain a principal that is listed. By - default, no AuthorizedPrincipalsCommand is run. + default, no AuthorizedPrincipalsCommand is run. This command is + only executed for valid users. AuthorizedPrincipalsCommandUser Specifies the user under whose account the @@ -190,12 +194,14 @@ DESCRIPTION options (as described in AUTHORIZED_KEYS FILE FORMAT in sshd(8)). Empty lines and comments starting with M-bM-^@M-^X#M-bM-^@M-^Y are ignored. - Arguments to AuthorizedPrincipalsFile accept the tokens described - in the TOKENS section. After expansion, AuthorizedPrincipalsFile - is taken to be an absolute path or one relative to the user's - home directory. The default is none, i.e. not to use a - principals file M-bM-^@M-^S in this case, the username of the user must - appear in a certificate's principals list for it to be accepted. + Arguments to AuthorizedPrincipalsFile may include wildcards and + accept the tokens described in the TOKENS section. After + expansion, AuthorizedPrincipalsFile is taken to be an absolute + path or one relative to the user's home directory. The default + is none, i.e. not to use a principals file M-bM-^@M-^S in this case, the + username of the user must appear in a certificate's principals + list for it to be accepted. This file is only checked for valid + users. Note that AuthorizedPrincipalsFile is only used when authentication proceeds using a CA listed in TrustedUserCAKeys @@ -252,13 +258,13 @@ DESCRIPTION direct-tcpip, direct-streamlocal@openssh.com Open TCP or Unix socket (respectively) connections that - have been established from a ssh(1) local forwarding, + have been established from an ssh(1) local forwarding, i.e. LocalForward or DynamicForward. forwarded-tcpip, forwarded-streamlocal@openssh.com Open TCP or Unix socket (respectively) connections that - have been established to a sshd(8) listening on behalf of - a ssh(1) remote forwarding, i.e. RemoteForward. + have been established to an sshd(8) listening on behalf + of an ssh(1) remote forwarding, i.e. RemoteForward. session The interactive main session, including shell session, @@ -336,8 +342,8 @@ DESCRIPTION The default is: chacha20-poly1305@openssh.com, - aes128-ctr,aes192-ctr,aes256-ctr, - aes128-gcm@openssh.com,aes256-gcm@openssh.com + aes128-gcm@openssh.com,aes256-gcm@openssh.com, + aes128-ctr,aes192-ctr,aes256-ctr The list of available ciphers may also be obtained using "ssh -Q cipher". @@ -378,9 +384,8 @@ DESCRIPTION separated by spaces. Login is disallowed for users whose primary group or supplementary group list matches one of the patterns. Only group names are valid; a numerical group ID is not - recognized. By default, login is allowed for all groups. The - allow/deny groups directives are processed in the following - order: DenyGroups, AllowGroups. + recognized. By default, login is allowed for all groups. + AllowGroups is not consulted for groups matched by DenyGroups. See PATTERNS in ssh_config(5) for more information on patterns. This keyword may appear multiple times in sshd_config with each @@ -395,8 +400,8 @@ DESCRIPTION then USER and HOST are separately checked, restricting logins to particular users from particular hosts. HOST criteria may additionally contain addresses to match in CIDR address/masklen - format. The allow/deny users directives are processed in the - following order: DenyUsers, AllowUsers. + format. AllowUsers is not consulted for users matched by + DenyUsers. See PATTERNS in ssh_config(5) for more information on patterns. This keyword may appear multiple times in sshd_config with each @@ -430,6 +435,12 @@ DESCRIPTION that requires no support files when used with ChrootDirectory. The default is none. + This directive does not limit other kinds of access that a client + may request via their connection, such as TCP, agent, socket or + X11 forwarding. If these are not desired, then they must be + explicitly disabled, either individually via their respective + options or all together using the DisableForwarding option. + GatewayPorts Specifies whether remote hosts are allowed to connect to ports forwarded for the client. By default, sshd(8) binds remote port @@ -451,6 +462,10 @@ DESCRIPTION Specifies whether to automatically destroy the user's credentials cache on logout. The default is yes. + GSSAPIDelegateCredentials + Accept delegated credentials on the server side. The default is + yes. + GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. If set to yes then the @@ -479,12 +494,14 @@ DESCRIPTION ecdsa-sha2-nistp521-cert-v01@openssh.com, sk-ssh-ed25519-cert-v01@openssh.com, sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, + webauthn-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, rsa-sha2-512-cert-v01@openssh.com, rsa-sha2-256-cert-v01@openssh.com, ssh-ed25519, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, sk-ssh-ed25519@openssh.com, sk-ecdsa-sha2-nistp256@openssh.com, + webauthn-sk-ecdsa-sha2-nistp256@openssh.com, rsa-sha2-512,rsa-sha2-256 The list of available signature algorithms may also be obtained @@ -541,12 +558,14 @@ DESCRIPTION ecdsa-sha2-nistp521-cert-v01@openssh.com, sk-ssh-ed25519-cert-v01@openssh.com, sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, + webauthn-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, rsa-sha2-512-cert-v01@openssh.com, rsa-sha2-256-cert-v01@openssh.com, ssh-ed25519, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, sk-ssh-ed25519@openssh.com, sk-ecdsa-sha2-nistp256@openssh.com, + webauthn-sk-ecdsa-sha2-nistp256@openssh.com, rsa-sha2-512,rsa-sha2-256 The list of available signature algorithms may also be obtained @@ -575,18 +594,18 @@ DESCRIPTION directive may appear inside a Match block to perform conditional inclusion. - IPQoS Specifies the IPv4 type-of-service or DSCP class for the - connection. Accepted values are af11, af12, af13, af21, af22, - af23, af31, af32, af33, af41, af42, af43, cs0, cs1, cs2, cs3, - cs4, cs5, cs6, cs7, ef, le, lowdelay, throughput, reliability, a - numeric value, or none to use the operating system default. This - option may take one or two arguments, separated by whitespace. - If one argument is specified, it is used as the packet class - unconditionally. If two values are specified, the first is - automatically selected for interactive sessions and the second - for non-interactive sessions. The default is af21 (Low-Latency - Data) for interactive sessions and cs1 (Lower Effort) for non- - interactive sessions. + IPQoS Specifies the Differentiated Services Field Codepoint (DSCP) + value for the connection. Accepted values are af11, af12, af13, + af21, af22, af23, af31, af32, af33, af41, af42, af43, cs0, cs1, + cs2, cs3, cs4, cs5, cs6, cs7, ef, le, a numeric value, or none to + use the operating system default. This option may take one or + two arguments, separated by whitespace. If one argument is + specified, it is used as the packet class unconditionally. If + two values are specified, the first is automatically selected for + interactive sessions and the second for non-interactive sessions. + The default is ef (Expedited Forwarding) for interactive sessions + and none (the operating system default) for non-interactive + sessions. KbdInteractiveAuthentication Specifies whether to allow keyboard-interactive authentication. @@ -650,13 +669,10 @@ DESCRIPTION The default is: - sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com, mlkem768x25519-sha256, + sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com, curve25519-sha256,curve25519-sha256@libssh.org, - ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, - diffie-hellman-group-exchange-sha256, - diffie-hellman-group16-sha512,diffie-hellman-group18-sha512, - diffie-hellman-group14-sha256 + ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521 The list of supported key exchange algorithms may also be obtained using "ssh -Q KexAlgorithms". @@ -759,9 +775,9 @@ DESCRIPTION one of the single token criteria: All, which matches all criteria, or Invalid-User, which matches when the requested user- name does not match any known account. The available criteria - are User, Group, Host, LocalAddress, LocalPort, RDomain, and - Address (with RDomain representing the rdomain(4) on which the - connection was received). + are User, Group, Host, LocalAddress, LocalPort, Version, RDomain, + and Address (with RDomain representing the rdomain(4) on which + the connection was received). The match patterns may consist of single entries or comma- separated lists and may use the wildcard and negation operators @@ -775,6 +791,9 @@ DESCRIPTION with bits set in this host portion of the address. For example, 192.0.2.0/33 and 192.0.2.0/8, respectively. + The Version keyword matches against the version string of + sshd(8), for example M-bM-^@M-^\OpenSSH_10.0M-bM-^@M-^]. + Only a subset of keywords may be used on the lines following a Match keyword. Available keywords are AcceptEnv, AllowAgentForwarding, AllowGroups, AllowStreamLocalForwarding, @@ -816,15 +835,16 @@ DESCRIPTION Specifies the maximum number of concurrent unauthenticated connections to the SSH daemon. Additional connections will be dropped until authentication succeeds or the LoginGraceTime - expires for a connection. The default is 10:30:100. + expires for a connection. Alternatively, random early drop can be enabled by specifying the three colon separated values start:rate:full (e.g. "10:30:60"). - sshd(8) will refuse connection attempts with a probability of - rate/100 (30%) if there are currently start (10) unauthenticated - connections. The probability increases linearly and all - connection attempts are refused if the number of unauthenticated - connections reaches full (60). + The default is 10:30:100. sshd(8) will refuse connection + attempts with a probability of rate/100 (30%) if there are + currently start (10) unauthenticated connections. The + probability increases linearly and all connection attempts are + refused if the number of unauthenticated connections reaches full + (60). ModuliFile Specifies the moduli(5) file that contains the Diffie-Hellman @@ -970,6 +990,10 @@ DESCRIPTION after making one or more unsuccessful authentication attempts (default: 5s). + invaliduser:duration + Specifies how long to refuse clients that attempt to log + in with an invalid user (default: 5s). + refuseconnection:duration Specifies how long to refuse clients that were administratively prohibited connection via the @@ -1065,12 +1089,14 @@ DESCRIPTION ecdsa-sha2-nistp521-cert-v01@openssh.com, sk-ssh-ed25519-cert-v01@openssh.com, sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, + webauthn-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, rsa-sha2-512-cert-v01@openssh.com, rsa-sha2-256-cert-v01@openssh.com, ssh-ed25519, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, sk-ssh-ed25519@openssh.com, sk-ecdsa-sha2-nistp256@openssh.com, + webauthn-sk-ecdsa-sha2-nistp256@openssh.com, rsa-sha2-512,rsa-sha2-256 The list of available signature algorithms may also be obtained @@ -1134,8 +1160,12 @@ DESCRIPTION public key authentication will be refused for all users. Keys may be specified as a text file, listing one public key per line, or as an OpenSSH Key Revocation List (KRL) as generated by - ssh-keygen(1). For more information on KRLs, see the KEY - REVOCATION LISTS section in ssh-keygen(1). + ssh-keygen(1). This file may be consulted for each public key + authentication attempt received by sshd(8) and its contents must + be consistent at all times, therefore it should only be + atomically replaced and never modified in place while the server + is running. For more information on KRLs, see the KEY REVOCATION + LISTS section in ssh-keygen(1). RDomain Specifies an explicit routing domain that is applied after @@ -1156,6 +1186,12 @@ DESCRIPTION environment and any variables specified by the user via AcceptEnv or PermitUserEnvironment. + SshdAuthPath + Overrides the default path to the sshd-auth binary that is + invoked to complete user authentication. The default is + /usr/libexec/sshd-auth. This option is intended for use by + tests. + SshdSessionPath Overrides the default path to the sshd-session binary that is invoked to handle each connection. The default is @@ -1357,7 +1393,11 @@ TIME FORMATS TOKENS Arguments to some keywords can make use of tokens, which are expanded at - runtime: + runtime. Tokens are expanded without quoting or escaping of shell + characters. It is the administrator's responsibility to ensure they are + safe in the context of their use. + + The supported tokens in sshd_config are: %% A literal M-bM-^@M-^X%M-bM-^@M-^Y. %C Identifies the connection endpoints, containing four space- @@ -1408,4 +1448,4 @@ AUTHORS versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support for privilege separation. -OpenBSD 7.6 September 15, 2024 OpenBSD 7.6 +OpenBSD 7.8 March 28, 2026 SSHD_CONFIG(5) diff --git a/sshd_config.5 b/sshd_config.5 index dbed44f..3f5e298 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.374 2024/09/15 08:27:38 jmc Exp $ -.Dd $Mdocdate: September 15 2024 $ +.\" $OpenBSD: sshd_config.5,v 1.397 2026/03/28 05:07:12 djm Exp $ +.Dd $Mdocdate: March 28 2026 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME @@ -113,9 +113,9 @@ If specified, login is allowed only for users whose primary group or supplementary group list matches one of the patterns. Only group names are valid; a numerical group ID is not recognized. By default, login is allowed for all groups. -The allow/deny groups directives are processed in the following order: -.Cm DenyGroups , -.Cm AllowGroups . +.Cm AllowGroups +is not consulted for groups matched by +.Cm DenyGroups . .Pp See PATTERNS in .Xr ssh_config 5 @@ -173,9 +173,9 @@ are separately checked, restricting logins to particular users from particular hosts. HOST criteria may additionally contain addresses to match in CIDR address/masklen format. -The allow/deny users directives are processed in the following order: -.Cm DenyUsers , -.Cm AllowUsers . +.Cm AllowUsers +is not consulted for users matched by +.Cm DenyUsers . .Pp See PATTERNS in .Xr ssh_config 5 @@ -250,7 +250,7 @@ If no arguments are specified then the username of the target user is used. .Pp The program should produce on standard output zero or more lines of authorized_keys output (see -.Sx AUTHORIZED_KEYS +.Cm AUTHORIZED_KEYS in .Xr sshd 8 ) . .Cm AuthorizedKeysCommand @@ -260,6 +260,7 @@ files and will not be executed if a matching key is found there. By default, no .Cm AuthorizedKeysCommand is run. +This command is only executed for valid users. .It Cm AuthorizedKeysCommandUser Specifies the user under whose account the .Cm AuthorizedKeysCommand @@ -279,7 +280,7 @@ The format is described in the AUTHORIZED_KEYS FILE FORMAT section of .Xr sshd 8 . Arguments to .Cm AuthorizedKeysFile -accept the tokens described in the +may include wildcards and accept the tokens described in the .Sx TOKENS section. After expansion, @@ -292,6 +293,7 @@ Alternately this option may be set to to skip checking for user keys in files. The default is .Qq .ssh/authorized_keys .ssh/authorized_keys2 . +These files are only checked for valid users. .It Cm AuthorizedPrincipalsCommand Specifies a program to be used to generate the list of allowed certificate principals as per @@ -318,6 +320,7 @@ must contain a principal that is listed. By default, no .Cm AuthorizedPrincipalsCommand is run. +This command is only executed for valid users. .It Cm AuthorizedPrincipalsCommandUser Specifies the user under whose account the .Cm AuthorizedPrincipalsCommand @@ -339,7 +342,7 @@ When using certificates signed by a key listed in this file lists names, one of which must appear in the certificate for it to be accepted for authentication. Names are listed one per line preceded by key options (as described in -.Sx AUTHORIZED_KEYS FILE FORMAT +.Cm AUTHORIZED_KEYS FILE FORMAT in .Xr sshd 8 ) . Empty lines and comments starting with @@ -348,7 +351,7 @@ are ignored. .Pp Arguments to .Cm AuthorizedPrincipalsFile -accept the tokens described in the +may include wildcards and accept the tokens described in the .Sx TOKENS section. After expansion, @@ -359,6 +362,7 @@ The default is i.e. not to use a principals file \(en in this case, the username of the user must appear in a certificate's principals list for it to be accepted. +This file is only checked for valid users. .Pp Note that .Cm AuthorizedPrincipalsFile @@ -440,7 +444,7 @@ Open connections to .Xr ssh-agent 1 . .It Cm direct-tcpip , Cm direct-streamlocal@openssh.com Open TCP or Unix socket (respectively) connections that have -been established from a +been established from an .Xr ssh 1 local forwarding, i.e.\& .Cm LocalForward @@ -448,9 +452,9 @@ or .Cm DynamicForward . .It Cm forwarded-tcpip , Cm forwarded-streamlocal@openssh.com Open TCP or Unix socket (respectively) connections that have been -established to a +established to an .Xr sshd 8 -listening on behalf of a +listening on behalf of an .Xr ssh 1 remote forwarding, i.e.\& .Cm RemoteForward . @@ -576,8 +580,8 @@ chacha20-poly1305@openssh.com The default is: .Bd -literal -offset indent chacha20-poly1305@openssh.com, -aes128-ctr,aes192-ctr,aes256-ctr, -aes128-gcm@openssh.com,aes256-gcm@openssh.com +aes128-gcm@openssh.com,aes256-gcm@openssh.com, +aes128-ctr,aes192-ctr,aes256-ctr .Ed .Pp The list of available ciphers may also be obtained using @@ -636,9 +640,9 @@ Login is disallowed for users whose primary group or supplementary group list matches one of the patterns. Only group names are valid; a numerical group ID is not recognized. By default, login is allowed for all groups. -The allow/deny groups directives are processed in the following order: -.Cm DenyGroups , -.Cm AllowGroups . +.Cm AllowGroups +is not consulted for groups matched by +.Cm DenyGroups . .Pp See PATTERNS in .Xr ssh_config 5 @@ -657,9 +661,9 @@ are separately checked, restricting logins to particular users from particular hosts. HOST criteria may additionally contain addresses to match in CIDR address/masklen format. -The allow/deny users directives are processed in the following order: -.Cm DenyUsers , -.Cm AllowUsers . +.Cm AllowUsers +is not consulted for users matched by +.Cm DenyUsers . .Pp See PATTERNS in .Xr ssh_config 5 @@ -710,6 +714,14 @@ files when used with .Cm ChrootDirectory . The default is .Cm none . +.Pp +This directive does not limit other kinds of access that a +client may request via their connection, such as TCP, agent, socket or +X11 forwarding. +If these are not desired, then they must be explicitly disabled, either +individually via their respective options or all together using the +.Cm DisableForwarding +option. .It Cm GatewayPorts Specifies whether remote hosts are allowed to connect to ports forwarded for the client. @@ -739,6 +751,10 @@ Specifies whether to automatically destroy the user's credentials cache on logout. The default is .Cm yes . +.It Cm GSSAPIDelegateCredentials +Accept delegated credentials on the server side. +The default is +.Cm yes . .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. @@ -776,12 +792,14 @@ ecdsa-sha2-nistp384-cert-v01@openssh.com, ecdsa-sha2-nistp521-cert-v01@openssh.com, sk-ssh-ed25519-cert-v01@openssh.com, sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, +webauthn-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, rsa-sha2-512-cert-v01@openssh.com, rsa-sha2-256-cert-v01@openssh.com, ssh-ed25519, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, sk-ssh-ed25519@openssh.com, sk-ecdsa-sha2-nistp256@openssh.com, +webauthn-sk-ecdsa-sha2-nistp256@openssh.com, rsa-sha2-512,rsa-sha2-256 .Ed .Pp @@ -860,12 +878,14 @@ ecdsa-sha2-nistp384-cert-v01@openssh.com, ecdsa-sha2-nistp521-cert-v01@openssh.com, sk-ssh-ed25519-cert-v01@openssh.com, sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, +webauthn-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, rsa-sha2-512-cert-v01@openssh.com, rsa-sha2-256-cert-v01@openssh.com, ssh-ed25519, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, sk-ssh-ed25519@openssh.com, sk-ecdsa-sha2-nistp256@openssh.com, +webauthn-sk-ecdsa-sha2-nistp256@openssh.com, rsa-sha2-512,rsa-sha2-256 .Ed .Pp @@ -923,7 +943,9 @@ directive may appear inside a block to perform conditional inclusion. .It Cm IPQoS -Specifies the IPv4 type-of-service or DSCP class for the connection. +Specifies the +.Em Differentiated Services Field Codepoint Pq DSCP +value for the connection. Accepted values are .Cm af11 , .Cm af12 , @@ -947,9 +969,6 @@ Accepted values are .Cm cs7 , .Cm ef , .Cm le , -.Cm lowdelay , -.Cm throughput , -.Cm reliability , a numeric value, or .Cm none to use the operating system default. @@ -958,11 +977,11 @@ If one argument is specified, it is used as the packet class unconditionally. If two values are specified, the first is automatically selected for interactive sessions and the second for non-interactive sessions. The default is -.Cm af21 -(Low-Latency Data) +.Cm ef +(Expedited Forwarding) for interactive sessions and -.Cm cs1 -(Lower Effort) +.Cm none +(the operating system default) for non-interactive sessions. .It Cm KbdInteractiveAuthentication Specifies whether to allow keyboard-interactive authentication. @@ -1059,13 +1078,10 @@ sntrup761x25519-sha512@openssh.com .Pp The default is: .Bd -literal -offset indent -sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com, mlkem768x25519-sha256, +sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com, curve25519-sha256,curve25519-sha256@libssh.org, -ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, -diffie-hellman-group-exchange-sha256, -diffie-hellman-group16-sha512,diffie-hellman-group18-sha512, -diffie-hellman-group14-sha256 +ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521 .Ed .Pp The list of supported key exchange algorithms may also be obtained using @@ -1248,6 +1264,7 @@ The available criteria are .Cm Host , .Cm LocalAddress , .Cm LocalPort , +.Cm Version , .Cm RDomain , and .Cm Address @@ -1273,6 +1290,13 @@ it is an error to specify a mask length that is too long for the address or one with bits set in this host portion of the address. For example, 192.0.2.0/33 and 192.0.2.0/8, respectively. .Pp +The +.Cm Version +keyword matches against the version string of +.Xr sshd 8 , +for example +.Dq OpenSSH_10.0 . +.Pp Only a subset of keywords may be used on the lines following a .Cm Match keyword. @@ -1362,11 +1386,11 @@ SSH daemon. Additional connections will be dropped until authentication succeeds or the .Cm LoginGraceTime expires for a connection. -The default is 10:30:100. .Pp Alternatively, random early drop can be enabled by specifying the three colon separated values start:rate:full (e.g. "10:30:60"). +The default is 10:30:100. .Xr sshd 8 will refuse connection attempts with a probability of rate/100 (30%) if there are currently start (10) unauthenticated connections. @@ -1607,6 +1631,9 @@ Specifies how long to refuse clients that cause a crash of .It Cm authfail:duration Specifies how long to refuse clients that disconnect after making one or more unsuccessful authentication attempts (default: 5s). +.It Cm invaliduser:duration +Specifies how long to refuse clients that attempt to log in with an invalid +user (default: 5s). .It Cm refuseconnection:duration Specifies how long to refuse clients that were administratively prohibited connection via the @@ -1719,12 +1746,14 @@ ecdsa-sha2-nistp384-cert-v01@openssh.com, ecdsa-sha2-nistp521-cert-v01@openssh.com, sk-ssh-ed25519-cert-v01@openssh.com, sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, +webauthn-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com, rsa-sha2-512-cert-v01@openssh.com, rsa-sha2-256-cert-v01@openssh.com, ssh-ed25519, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, sk-ssh-ed25519@openssh.com, sk-ecdsa-sha2-nistp256@openssh.com, +webauthn-sk-ecdsa-sha2-nistp256@openssh.com, rsa-sha2-512,rsa-sha2-256 .Ed .Pp @@ -1826,6 +1855,11 @@ be refused for all users. Keys may be specified as a text file, listing one public key per line, or as an OpenSSH Key Revocation List (KRL) as generated by .Xr ssh-keygen 1 . +This file may be consulted for each public key authentication attempt +received by +.Xr sshd 8 +and its contents must be consistent at all times, therefore it should only +be atomically replaced and never modified in place while the server is running. For more information on KRLs, see the KEY REVOCATION LISTS section in .Xr ssh-keygen 1 . .It Cm RDomain @@ -1856,6 +1890,13 @@ via .Cm AcceptEnv or .Cm PermitUserEnvironment . +.It Cm SshdAuthPath +Overrides the default path to the +.Cm sshd-auth +binary that is invoked to complete user authentication. +The default is +.Pa /usr/libexec/sshd-auth . +This option is intended for use by tests. .It Cm SshdSessionPath Overrides the default path to the .Cm sshd-session @@ -2157,7 +2198,14 @@ Time format examples: .El .Sh TOKENS Arguments to some keywords can make use of tokens, -which are expanded at runtime: +which are expanded at runtime. +Tokens are expanded without quoting or escaping of shell characters. +It is the administrator's responsibility to ensure they are safe in the +context of their use. +.Pp +The supported tokens in +.Nm +are: .Pp .Bl -tag -width XXXX -offset indent -compact .It %% diff --git a/ssherr-libcrypto.c b/ssherr-libcrypto.c new file mode 100644 index 0000000..5b817e5 --- /dev/null +++ b/ssherr-libcrypto.c @@ -0,0 +1,59 @@ +/* $OpenBSD: ssherr-libcrypto.c,v 1.1 2026/02/06 23:31:29 dtucker Exp $ */ +/* + * Copyright (c) 2026 Darren Tucker + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +#include "includes.h" + +#include + +#include +#include + +#include "log.h" + +#ifdef WITH_OPENSSL +#include + +const char * +ssherr_libcrypto(void) +{ + unsigned long e; + static char buf[512]; + char msg[4096]; + const char *reason = NULL, *file, *data; + int ln, fl; + + ERR_load_crypto_strings(); + while ((e = ERR_get_error_line_data(&file, &ln, &data, &fl)) != 0) { + ERR_error_string_n(e, buf, sizeof(buf)); + snprintf(msg, sizeof(msg), "%s:%s:%d:%s", buf, file, ln, + (fl & ERR_TXT_STRING) ? data : ""); + debug("libcrypto: '%s'", msg); + if ((reason = ERR_reason_error_string(e)) != NULL) + snprintf(buf, sizeof(buf), "error in libcrypto: %s", + reason); + } + if (reason == NULL) + return NULL; + return buf; +} +#else +const char * +ssherr_libcrypto(void) +{ + return NULL; +} +#endif diff --git a/ssherr-nolibcrypto.c b/ssherr-nolibcrypto.c new file mode 100644 index 0000000..039d69d --- /dev/null +++ b/ssherr-nolibcrypto.c @@ -0,0 +1,26 @@ +/* $OpenBSD: ssherr-nolibcrypto.c,v 1.1 2026/02/06 23:31:29 dtucker Exp $ */ +/* + * Copyright (c) 2026 Darren Tucker + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +#include + +#include "ssherr.h" + +const char * +ssherr_libcrypto(void) +{ + return NULL; +} diff --git a/ssherr.c b/ssherr.c index bd954aa..d22072d 100644 --- a/ssherr.c +++ b/ssherr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssherr.c,v 1.10 2020/01/25 23:13:09 djm Exp $ */ +/* $OpenBSD: ssherr.c,v 1.11 2026/02/06 23:31:29 dtucker Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -22,6 +22,8 @@ const char * ssh_err(int n) { + const char *msg = NULL; + switch (n) { case SSH_ERR_SUCCESS: return "success"; @@ -68,7 +70,8 @@ ssh_err(int n) case SSH_ERR_SIGNATURE_INVALID: return "incorrect signature"; case SSH_ERR_LIBCRYPTO_ERROR: - return "error in libcrypto"; /* XXX fetch and return */ + msg = ssherr_libcrypto(); + return msg != NULL ? msg : "error in libcrypto"; case SSH_ERR_UNEXPECTED_TRAILING_DATA: return "unexpected bytes remain after decoding"; case SSH_ERR_SYSTEM_ERROR: diff --git a/ssherr.h b/ssherr.h index 085e752..3dac27a 100644 --- a/ssherr.h +++ b/ssherr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssherr.h,v 1.8 2020/01/25 23:13:09 djm Exp $ */ +/* $OpenBSD: ssherr.h,v 1.9 2026/02/06 23:31:29 dtucker Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -85,5 +85,7 @@ /* Translate a numeric error code to a human-readable error string */ const char *ssh_err(int n); +/* Return most recent error from libcrypto. */ +const char *ssherr_libcrypto(void); #endif /* _SSHERR_H */ diff --git a/sshkey-xmss.c b/sshkey-xmss.c deleted file mode 100644 index 818aba9..0000000 --- a/sshkey-xmss.c +++ /dev/null @@ -1,1113 +0,0 @@ -/* $OpenBSD: sshkey-xmss.c,v 1.12 2022/10/28 00:39:29 djm Exp $ */ -/* - * Copyright (c) 2017 Markus Friedl. 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" -#ifdef WITH_XMSS - -#include -#include - -#include -#include -#include -#include -#include -#ifdef HAVE_SYS_FILE_H -# include -#endif - -#include "ssh2.h" -#include "ssherr.h" -#include "sshbuf.h" -#include "cipher.h" -#include "sshkey.h" -#include "sshkey-xmss.h" -#include "atomicio.h" -#include "log.h" - -#include "xmss_fast.h" - -/* opaque internal XMSS state */ -#define XMSS_MAGIC "xmss-state-v1" -#define XMSS_CIPHERNAME "aes256-gcm@openssh.com" -struct ssh_xmss_state { - xmss_params params; - u_int32_t n, w, h, k; - - bds_state bds; - u_char *stack; - u_int32_t stackoffset; - u_char *stacklevels; - u_char *auth; - u_char *keep; - u_char *th_nodes; - u_char *retain; - treehash_inst *treehash; - - u_int32_t idx; /* state read from file */ - u_int32_t maxidx; /* restricted # of signatures */ - int have_state; /* .state file exists */ - int lockfd; /* locked in sshkey_xmss_get_state() */ - u_char allow_update; /* allow sshkey_xmss_update_state() */ - char *enc_ciphername;/* encrypt state with cipher */ - u_char *enc_keyiv; /* encrypt state with key */ - u_int32_t enc_keyiv_len; /* length of enc_keyiv */ -}; - -int sshkey_xmss_init_bds_state(struct sshkey *); -int sshkey_xmss_init_enc_key(struct sshkey *, const char *); -void sshkey_xmss_free_bds(struct sshkey *); -int sshkey_xmss_get_state_from_file(struct sshkey *, const char *, - int *, int); -int sshkey_xmss_encrypt_state(const struct sshkey *, struct sshbuf *, - struct sshbuf **); -int sshkey_xmss_decrypt_state(const struct sshkey *, struct sshbuf *, - struct sshbuf **); -int sshkey_xmss_serialize_enc_key(const struct sshkey *, struct sshbuf *); -int sshkey_xmss_deserialize_enc_key(struct sshkey *, struct sshbuf *); - -#define PRINT(...) do { if (printerror) sshlog(__FILE__, __func__, __LINE__, \ - 0, SYSLOG_LEVEL_ERROR, NULL, __VA_ARGS__); } while (0) - -int -sshkey_xmss_init(struct sshkey *key, const char *name) -{ - struct ssh_xmss_state *state; - - if (key->xmss_state != NULL) - return SSH_ERR_INVALID_FORMAT; - if (name == NULL) - return SSH_ERR_INVALID_FORMAT; - state = calloc(sizeof(struct ssh_xmss_state), 1); - if (state == NULL) - return SSH_ERR_ALLOC_FAIL; - if (strcmp(name, XMSS_SHA2_256_W16_H10_NAME) == 0) { - state->n = 32; - state->w = 16; - state->h = 10; - } else if (strcmp(name, XMSS_SHA2_256_W16_H16_NAME) == 0) { - state->n = 32; - state->w = 16; - state->h = 16; - } else if (strcmp(name, XMSS_SHA2_256_W16_H20_NAME) == 0) { - state->n = 32; - state->w = 16; - state->h = 20; - } else { - free(state); - return SSH_ERR_KEY_TYPE_UNKNOWN; - } - if ((key->xmss_name = strdup(name)) == NULL) { - free(state); - return SSH_ERR_ALLOC_FAIL; - } - state->k = 2; /* XXX hardcoded */ - state->lockfd = -1; - if (xmss_set_params(&state->params, state->n, state->h, state->w, - state->k) != 0) { - free(state); - return SSH_ERR_INVALID_FORMAT; - } - key->xmss_state = state; - return 0; -} - -void -sshkey_xmss_free_state(struct sshkey *key) -{ - struct ssh_xmss_state *state = key->xmss_state; - - sshkey_xmss_free_bds(key); - if (state) { - if (state->enc_keyiv) { - explicit_bzero(state->enc_keyiv, state->enc_keyiv_len); - free(state->enc_keyiv); - } - free(state->enc_ciphername); - free(state); - } - key->xmss_state = NULL; -} - -#define SSH_XMSS_K2_MAGIC "k=2" -#define num_stack(x) ((x->h+1)*(x->n)) -#define num_stacklevels(x) (x->h+1) -#define num_auth(x) ((x->h)*(x->n)) -#define num_keep(x) ((x->h >> 1)*(x->n)) -#define num_th_nodes(x) ((x->h - x->k)*(x->n)) -#define num_retain(x) (((1ULL << x->k) - x->k - 1) * (x->n)) -#define num_treehash(x) ((x->h) - (x->k)) - -int -sshkey_xmss_init_bds_state(struct sshkey *key) -{ - struct ssh_xmss_state *state = key->xmss_state; - u_int32_t i; - - state->stackoffset = 0; - if ((state->stack = calloc(num_stack(state), 1)) == NULL || - (state->stacklevels = calloc(num_stacklevels(state), 1))== NULL || - (state->auth = calloc(num_auth(state), 1)) == NULL || - (state->keep = calloc(num_keep(state), 1)) == NULL || - (state->th_nodes = calloc(num_th_nodes(state), 1)) == NULL || - (state->retain = calloc(num_retain(state), 1)) == NULL || - (state->treehash = calloc(num_treehash(state), - sizeof(treehash_inst))) == NULL) { - sshkey_xmss_free_bds(key); - return SSH_ERR_ALLOC_FAIL; - } - for (i = 0; i < state->h - state->k; i++) - state->treehash[i].node = &state->th_nodes[state->n*i]; - xmss_set_bds_state(&state->bds, state->stack, state->stackoffset, - state->stacklevels, state->auth, state->keep, state->treehash, - state->retain, 0); - return 0; -} - -void -sshkey_xmss_free_bds(struct sshkey *key) -{ - struct ssh_xmss_state *state = key->xmss_state; - - if (state == NULL) - return; - free(state->stack); - free(state->stacklevels); - free(state->auth); - free(state->keep); - free(state->th_nodes); - free(state->retain); - free(state->treehash); - state->stack = NULL; - state->stacklevels = NULL; - state->auth = NULL; - state->keep = NULL; - state->th_nodes = NULL; - state->retain = NULL; - state->treehash = NULL; -} - -void * -sshkey_xmss_params(const struct sshkey *key) -{ - struct ssh_xmss_state *state = key->xmss_state; - - if (state == NULL) - return NULL; - return &state->params; -} - -void * -sshkey_xmss_bds_state(const struct sshkey *key) -{ - struct ssh_xmss_state *state = key->xmss_state; - - if (state == NULL) - return NULL; - return &state->bds; -} - -int -sshkey_xmss_siglen(const struct sshkey *key, size_t *lenp) -{ - struct ssh_xmss_state *state = key->xmss_state; - - if (lenp == NULL) - return SSH_ERR_INVALID_ARGUMENT; - if (state == NULL) - return SSH_ERR_INVALID_FORMAT; - *lenp = 4 + state->n + - state->params.wots_par.keysize + - state->h * state->n; - return 0; -} - -size_t -sshkey_xmss_pklen(const struct sshkey *key) -{ - struct ssh_xmss_state *state = key->xmss_state; - - if (state == NULL) - return 0; - return state->n * 2; -} - -size_t -sshkey_xmss_sklen(const struct sshkey *key) -{ - struct ssh_xmss_state *state = key->xmss_state; - - if (state == NULL) - return 0; - return state->n * 4 + 4; -} - -int -sshkey_xmss_init_enc_key(struct sshkey *k, const char *ciphername) -{ - struct ssh_xmss_state *state = k->xmss_state; - const struct sshcipher *cipher; - size_t keylen = 0, ivlen = 0; - - if (state == NULL) - return SSH_ERR_INVALID_ARGUMENT; - if ((cipher = cipher_by_name(ciphername)) == NULL) - return SSH_ERR_INTERNAL_ERROR; - if ((state->enc_ciphername = strdup(ciphername)) == NULL) - return SSH_ERR_ALLOC_FAIL; - keylen = cipher_keylen(cipher); - ivlen = cipher_ivlen(cipher); - state->enc_keyiv_len = keylen + ivlen; - if ((state->enc_keyiv = calloc(state->enc_keyiv_len, 1)) == NULL) { - free(state->enc_ciphername); - state->enc_ciphername = NULL; - return SSH_ERR_ALLOC_FAIL; - } - arc4random_buf(state->enc_keyiv, state->enc_keyiv_len); - return 0; -} - -int -sshkey_xmss_serialize_enc_key(const struct sshkey *k, struct sshbuf *b) -{ - struct ssh_xmss_state *state = k->xmss_state; - int r; - - if (state == NULL || state->enc_keyiv == NULL || - state->enc_ciphername == NULL) - return SSH_ERR_INVALID_ARGUMENT; - if ((r = sshbuf_put_cstring(b, state->enc_ciphername)) != 0 || - (r = sshbuf_put_string(b, state->enc_keyiv, - state->enc_keyiv_len)) != 0) - return r; - return 0; -} - -int -sshkey_xmss_deserialize_enc_key(struct sshkey *k, struct sshbuf *b) -{ - struct ssh_xmss_state *state = k->xmss_state; - size_t len; - int r; - - if (state == NULL) - return SSH_ERR_INVALID_ARGUMENT; - if ((r = sshbuf_get_cstring(b, &state->enc_ciphername, NULL)) != 0 || - (r = sshbuf_get_string(b, &state->enc_keyiv, &len)) != 0) - return r; - state->enc_keyiv_len = len; - return 0; -} - -int -sshkey_xmss_serialize_pk_info(const struct sshkey *k, struct sshbuf *b, - enum sshkey_serialize_rep opts) -{ - struct ssh_xmss_state *state = k->xmss_state; - u_char have_info = 1; - u_int32_t idx; - int r; - - if (state == NULL) - return SSH_ERR_INVALID_ARGUMENT; - if (opts != SSHKEY_SERIALIZE_INFO) - return 0; - idx = k->xmss_sk ? PEEK_U32(k->xmss_sk) : state->idx; - if ((r = sshbuf_put_u8(b, have_info)) != 0 || - (r = sshbuf_put_u32(b, idx)) != 0 || - (r = sshbuf_put_u32(b, state->maxidx)) != 0) - return r; - return 0; -} - -int -sshkey_xmss_deserialize_pk_info(struct sshkey *k, struct sshbuf *b) -{ - struct ssh_xmss_state *state = k->xmss_state; - u_char have_info; - int r; - - if (state == NULL) - return SSH_ERR_INVALID_ARGUMENT; - /* optional */ - if (sshbuf_len(b) == 0) - return 0; - if ((r = sshbuf_get_u8(b, &have_info)) != 0) - return r; - if (have_info != 1) - return SSH_ERR_INVALID_ARGUMENT; - if ((r = sshbuf_get_u32(b, &state->idx)) != 0 || - (r = sshbuf_get_u32(b, &state->maxidx)) != 0) - return r; - return 0; -} - -int -sshkey_xmss_generate_private_key(struct sshkey *k, int bits) -{ - int r; - const char *name; - - if (bits == 10) { - name = XMSS_SHA2_256_W16_H10_NAME; - } else if (bits == 16) { - name = XMSS_SHA2_256_W16_H16_NAME; - } else if (bits == 20) { - name = XMSS_SHA2_256_W16_H20_NAME; - } else { - name = XMSS_DEFAULT_NAME; - } - if ((r = sshkey_xmss_init(k, name)) != 0 || - (r = sshkey_xmss_init_bds_state(k)) != 0 || - (r = sshkey_xmss_init_enc_key(k, XMSS_CIPHERNAME)) != 0) - return r; - if ((k->xmss_pk = malloc(sshkey_xmss_pklen(k))) == NULL || - (k->xmss_sk = malloc(sshkey_xmss_sklen(k))) == NULL) { - return SSH_ERR_ALLOC_FAIL; - } - xmss_keypair(k->xmss_pk, k->xmss_sk, sshkey_xmss_bds_state(k), - sshkey_xmss_params(k)); - return 0; -} - -int -sshkey_xmss_get_state_from_file(struct sshkey *k, const char *filename, - int *have_file, int printerror) -{ - struct sshbuf *b = NULL, *enc = NULL; - int ret = SSH_ERR_SYSTEM_ERROR, r, fd = -1; - u_int32_t len; - unsigned char buf[4], *data = NULL; - - *have_file = 0; - if ((fd = open(filename, O_RDONLY)) >= 0) { - *have_file = 1; - if (atomicio(read, fd, buf, sizeof(buf)) != sizeof(buf)) { - PRINT("corrupt state file: %s", filename); - goto done; - } - len = PEEK_U32(buf); - if ((data = calloc(len, 1)) == NULL) { - ret = SSH_ERR_ALLOC_FAIL; - goto done; - } - if (atomicio(read, fd, data, len) != len) { - PRINT("cannot read blob: %s", filename); - goto done; - } - if ((enc = sshbuf_from(data, len)) == NULL) { - ret = SSH_ERR_ALLOC_FAIL; - goto done; - } - sshkey_xmss_free_bds(k); - if ((r = sshkey_xmss_decrypt_state(k, enc, &b)) != 0) { - ret = r; - goto done; - } - if ((r = sshkey_xmss_deserialize_state(k, b)) != 0) { - ret = r; - goto done; - } - ret = 0; - } -done: - if (fd != -1) - close(fd); - free(data); - sshbuf_free(enc); - sshbuf_free(b); - return ret; -} - -int -sshkey_xmss_get_state(const struct sshkey *k, int printerror) -{ - struct ssh_xmss_state *state = k->xmss_state; - u_int32_t idx = 0; - char *filename = NULL; - char *statefile = NULL, *ostatefile = NULL, *lockfile = NULL; - int lockfd = -1, have_state = 0, have_ostate, tries = 0; - int ret = SSH_ERR_INVALID_ARGUMENT, r; - - if (state == NULL) - goto done; - /* - * If maxidx is set, then we are allowed a limited number - * of signatures, but don't need to access the disk. - * Otherwise we need to deal with the on-disk state. - */ - if (state->maxidx) { - /* xmss_sk always contains the current state */ - idx = PEEK_U32(k->xmss_sk); - if (idx < state->maxidx) { - state->allow_update = 1; - return 0; - } - return SSH_ERR_INVALID_ARGUMENT; - } - if ((filename = k->xmss_filename) == NULL) - goto done; - if (asprintf(&lockfile, "%s.lock", filename) == -1 || - asprintf(&statefile, "%s.state", filename) == -1 || - asprintf(&ostatefile, "%s.ostate", filename) == -1) { - ret = SSH_ERR_ALLOC_FAIL; - goto done; - } - if ((lockfd = open(lockfile, O_CREAT|O_RDONLY, 0600)) == -1) { - ret = SSH_ERR_SYSTEM_ERROR; - PRINT("cannot open/create: %s", lockfile); - goto done; - } - while (flock(lockfd, LOCK_EX|LOCK_NB) == -1) { - if (errno != EWOULDBLOCK) { - ret = SSH_ERR_SYSTEM_ERROR; - PRINT("cannot lock: %s", lockfile); - goto done; - } - if (++tries > 10) { - ret = SSH_ERR_SYSTEM_ERROR; - PRINT("giving up on: %s", lockfile); - goto done; - } - usleep(1000*100*tries); - } - /* XXX no longer const */ - if ((r = sshkey_xmss_get_state_from_file((struct sshkey *)k, - statefile, &have_state, printerror)) != 0) { - if ((r = sshkey_xmss_get_state_from_file((struct sshkey *)k, - ostatefile, &have_ostate, printerror)) == 0) { - state->allow_update = 1; - r = sshkey_xmss_forward_state(k, 1); - state->idx = PEEK_U32(k->xmss_sk); - state->allow_update = 0; - } - } - if (!have_state && !have_ostate) { - /* check that bds state is initialized */ - if (state->bds.auth == NULL) - goto done; - PRINT("start from scratch idx 0: %u", state->idx); - } else if (r != 0) { - ret = r; - goto done; - } - if (state->idx + 1 < state->idx) { - PRINT("state wrap: %u", state->idx); - goto done; - } - state->have_state = have_state; - state->lockfd = lockfd; - state->allow_update = 1; - lockfd = -1; - ret = 0; -done: - if (lockfd != -1) - close(lockfd); - free(lockfile); - free(statefile); - free(ostatefile); - return ret; -} - -int -sshkey_xmss_forward_state(const struct sshkey *k, u_int32_t reserve) -{ - struct ssh_xmss_state *state = k->xmss_state; - u_char *sig = NULL; - size_t required_siglen; - unsigned long long smlen; - u_char data; - int ret, r; - - if (state == NULL || !state->allow_update) - return SSH_ERR_INVALID_ARGUMENT; - if (reserve == 0) - return SSH_ERR_INVALID_ARGUMENT; - if (state->idx + reserve <= state->idx) - return SSH_ERR_INVALID_ARGUMENT; - if ((r = sshkey_xmss_siglen(k, &required_siglen)) != 0) - return r; - if ((sig = malloc(required_siglen)) == NULL) - return SSH_ERR_ALLOC_FAIL; - while (reserve-- > 0) { - state->idx = PEEK_U32(k->xmss_sk); - smlen = required_siglen; - if ((ret = xmss_sign(k->xmss_sk, sshkey_xmss_bds_state(k), - sig, &smlen, &data, 0, sshkey_xmss_params(k))) != 0) { - r = SSH_ERR_INVALID_ARGUMENT; - break; - } - } - free(sig); - return r; -} - -int -sshkey_xmss_update_state(const struct sshkey *k, int printerror) -{ - struct ssh_xmss_state *state = k->xmss_state; - struct sshbuf *b = NULL, *enc = NULL; - u_int32_t idx = 0; - unsigned char buf[4]; - char *filename = NULL; - char *statefile = NULL, *ostatefile = NULL, *nstatefile = NULL; - int fd = -1; - int ret = SSH_ERR_INVALID_ARGUMENT; - - if (state == NULL || !state->allow_update) - return ret; - if (state->maxidx) { - /* no update since the number of signatures is limited */ - ret = 0; - goto done; - } - idx = PEEK_U32(k->xmss_sk); - if (idx == state->idx) { - /* no signature happened, no need to update */ - ret = 0; - goto done; - } else if (idx != state->idx + 1) { - PRINT("more than one signature happened: idx %u state %u", - idx, state->idx); - goto done; - } - state->idx = idx; - if ((filename = k->xmss_filename) == NULL) - goto done; - if (asprintf(&statefile, "%s.state", filename) == -1 || - asprintf(&ostatefile, "%s.ostate", filename) == -1 || - asprintf(&nstatefile, "%s.nstate", filename) == -1) { - ret = SSH_ERR_ALLOC_FAIL; - goto done; - } - unlink(nstatefile); - if ((b = sshbuf_new()) == NULL) { - ret = SSH_ERR_ALLOC_FAIL; - goto done; - } - if ((ret = sshkey_xmss_serialize_state(k, b)) != 0) { - PRINT("SERLIALIZE FAILED: %d", ret); - goto done; - } - if ((ret = sshkey_xmss_encrypt_state(k, b, &enc)) != 0) { - PRINT("ENCRYPT FAILED: %d", ret); - goto done; - } - if ((fd = open(nstatefile, O_CREAT|O_WRONLY|O_EXCL, 0600)) == -1) { - ret = SSH_ERR_SYSTEM_ERROR; - PRINT("open new state file: %s", nstatefile); - goto done; - } - POKE_U32(buf, sshbuf_len(enc)); - if (atomicio(vwrite, fd, buf, sizeof(buf)) != sizeof(buf)) { - ret = SSH_ERR_SYSTEM_ERROR; - PRINT("write new state file hdr: %s", nstatefile); - close(fd); - goto done; - } - if (atomicio(vwrite, fd, sshbuf_mutable_ptr(enc), sshbuf_len(enc)) != - sshbuf_len(enc)) { - ret = SSH_ERR_SYSTEM_ERROR; - PRINT("write new state file data: %s", nstatefile); - close(fd); - goto done; - } - if (fsync(fd) == -1) { - ret = SSH_ERR_SYSTEM_ERROR; - PRINT("sync new state file: %s", nstatefile); - close(fd); - goto done; - } - if (close(fd) == -1) { - ret = SSH_ERR_SYSTEM_ERROR; - PRINT("close new state file: %s", nstatefile); - goto done; - } - if (state->have_state) { - unlink(ostatefile); - if (link(statefile, ostatefile)) { - ret = SSH_ERR_SYSTEM_ERROR; - PRINT("backup state %s to %s", statefile, ostatefile); - goto done; - } - } - if (rename(nstatefile, statefile) == -1) { - ret = SSH_ERR_SYSTEM_ERROR; - PRINT("rename %s to %s", nstatefile, statefile); - goto done; - } - ret = 0; -done: - if (state->lockfd != -1) { - close(state->lockfd); - state->lockfd = -1; - } - if (nstatefile) - unlink(nstatefile); - free(statefile); - free(ostatefile); - free(nstatefile); - sshbuf_free(b); - sshbuf_free(enc); - return ret; -} - -int -sshkey_xmss_serialize_state(const struct sshkey *k, struct sshbuf *b) -{ - struct ssh_xmss_state *state = k->xmss_state; - treehash_inst *th; - u_int32_t i, node; - int r; - - if (state == NULL) - return SSH_ERR_INVALID_ARGUMENT; - if (state->stack == NULL) - return SSH_ERR_INVALID_ARGUMENT; - state->stackoffset = state->bds.stackoffset; /* copy back */ - if ((r = sshbuf_put_cstring(b, SSH_XMSS_K2_MAGIC)) != 0 || - (r = sshbuf_put_u32(b, state->idx)) != 0 || - (r = sshbuf_put_string(b, state->stack, num_stack(state))) != 0 || - (r = sshbuf_put_u32(b, state->stackoffset)) != 0 || - (r = sshbuf_put_string(b, state->stacklevels, num_stacklevels(state))) != 0 || - (r = sshbuf_put_string(b, state->auth, num_auth(state))) != 0 || - (r = sshbuf_put_string(b, state->keep, num_keep(state))) != 0 || - (r = sshbuf_put_string(b, state->th_nodes, num_th_nodes(state))) != 0 || - (r = sshbuf_put_string(b, state->retain, num_retain(state))) != 0 || - (r = sshbuf_put_u32(b, num_treehash(state))) != 0) - return r; - for (i = 0; i < num_treehash(state); i++) { - th = &state->treehash[i]; - node = th->node - state->th_nodes; - if ((r = sshbuf_put_u32(b, th->h)) != 0 || - (r = sshbuf_put_u32(b, th->next_idx)) != 0 || - (r = sshbuf_put_u32(b, th->stackusage)) != 0 || - (r = sshbuf_put_u8(b, th->completed)) != 0 || - (r = sshbuf_put_u32(b, node)) != 0) - return r; - } - return 0; -} - -int -sshkey_xmss_serialize_state_opt(const struct sshkey *k, struct sshbuf *b, - enum sshkey_serialize_rep opts) -{ - struct ssh_xmss_state *state = k->xmss_state; - int r = SSH_ERR_INVALID_ARGUMENT; - u_char have_stack, have_filename, have_enc; - - if (state == NULL) - return SSH_ERR_INVALID_ARGUMENT; - if ((r = sshbuf_put_u8(b, opts)) != 0) - return r; - switch (opts) { - case SSHKEY_SERIALIZE_STATE: - r = sshkey_xmss_serialize_state(k, b); - break; - case SSHKEY_SERIALIZE_FULL: - if ((r = sshkey_xmss_serialize_enc_key(k, b)) != 0) - return r; - r = sshkey_xmss_serialize_state(k, b); - break; - case SSHKEY_SERIALIZE_SHIELD: - /* all of stack/filename/enc are optional */ - have_stack = state->stack != NULL; - if ((r = sshbuf_put_u8(b, have_stack)) != 0) - return r; - if (have_stack) { - state->idx = PEEK_U32(k->xmss_sk); /* update */ - if ((r = sshkey_xmss_serialize_state(k, b)) != 0) - return r; - } - have_filename = k->xmss_filename != NULL; - if ((r = sshbuf_put_u8(b, have_filename)) != 0) - return r; - if (have_filename && - (r = sshbuf_put_cstring(b, k->xmss_filename)) != 0) - return r; - have_enc = state->enc_keyiv != NULL; - if ((r = sshbuf_put_u8(b, have_enc)) != 0) - return r; - if (have_enc && - (r = sshkey_xmss_serialize_enc_key(k, b)) != 0) - return r; - if ((r = sshbuf_put_u32(b, state->maxidx)) != 0 || - (r = sshbuf_put_u8(b, state->allow_update)) != 0) - return r; - break; - case SSHKEY_SERIALIZE_DEFAULT: - r = 0; - break; - default: - r = SSH_ERR_INVALID_ARGUMENT; - break; - } - return r; -} - -int -sshkey_xmss_deserialize_state(struct sshkey *k, struct sshbuf *b) -{ - struct ssh_xmss_state *state = k->xmss_state; - treehash_inst *th; - u_int32_t i, lh, node; - size_t ls, lsl, la, lk, ln, lr; - char *magic; - int r = SSH_ERR_INTERNAL_ERROR; - - if (state == NULL) - return SSH_ERR_INVALID_ARGUMENT; - if (k->xmss_sk == NULL) - return SSH_ERR_INVALID_ARGUMENT; - if ((state->treehash = calloc(num_treehash(state), - sizeof(treehash_inst))) == NULL) - return SSH_ERR_ALLOC_FAIL; - if ((r = sshbuf_get_cstring(b, &magic, NULL)) != 0 || - (r = sshbuf_get_u32(b, &state->idx)) != 0 || - (r = sshbuf_get_string(b, &state->stack, &ls)) != 0 || - (r = sshbuf_get_u32(b, &state->stackoffset)) != 0 || - (r = sshbuf_get_string(b, &state->stacklevels, &lsl)) != 0 || - (r = sshbuf_get_string(b, &state->auth, &la)) != 0 || - (r = sshbuf_get_string(b, &state->keep, &lk)) != 0 || - (r = sshbuf_get_string(b, &state->th_nodes, &ln)) != 0 || - (r = sshbuf_get_string(b, &state->retain, &lr)) != 0 || - (r = sshbuf_get_u32(b, &lh)) != 0) - goto out; - if (strcmp(magic, SSH_XMSS_K2_MAGIC) != 0) { - r = SSH_ERR_INVALID_ARGUMENT; - goto out; - } - /* XXX check stackoffset */ - if (ls != num_stack(state) || - lsl != num_stacklevels(state) || - la != num_auth(state) || - lk != num_keep(state) || - ln != num_th_nodes(state) || - lr != num_retain(state) || - lh != num_treehash(state)) { - r = SSH_ERR_INVALID_ARGUMENT; - goto out; - } - for (i = 0; i < num_treehash(state); i++) { - th = &state->treehash[i]; - if ((r = sshbuf_get_u32(b, &th->h)) != 0 || - (r = sshbuf_get_u32(b, &th->next_idx)) != 0 || - (r = sshbuf_get_u32(b, &th->stackusage)) != 0 || - (r = sshbuf_get_u8(b, &th->completed)) != 0 || - (r = sshbuf_get_u32(b, &node)) != 0) - goto out; - if (node < num_th_nodes(state)) - th->node = &state->th_nodes[node]; - } - POKE_U32(k->xmss_sk, state->idx); - xmss_set_bds_state(&state->bds, state->stack, state->stackoffset, - state->stacklevels, state->auth, state->keep, state->treehash, - state->retain, 0); - /* success */ - r = 0; - out: - free(magic); - return r; -} - -int -sshkey_xmss_deserialize_state_opt(struct sshkey *k, struct sshbuf *b) -{ - struct ssh_xmss_state *state = k->xmss_state; - enum sshkey_serialize_rep opts; - u_char have_state, have_stack, have_filename, have_enc; - int r; - - if ((r = sshbuf_get_u8(b, &have_state)) != 0) - return r; - - opts = have_state; - switch (opts) { - case SSHKEY_SERIALIZE_DEFAULT: - r = 0; - break; - case SSHKEY_SERIALIZE_SHIELD: - if ((r = sshbuf_get_u8(b, &have_stack)) != 0) - return r; - if (have_stack && - (r = sshkey_xmss_deserialize_state(k, b)) != 0) - return r; - if ((r = sshbuf_get_u8(b, &have_filename)) != 0) - return r; - if (have_filename && - (r = sshbuf_get_cstring(b, &k->xmss_filename, NULL)) != 0) - return r; - if ((r = sshbuf_get_u8(b, &have_enc)) != 0) - return r; - if (have_enc && - (r = sshkey_xmss_deserialize_enc_key(k, b)) != 0) - return r; - if ((r = sshbuf_get_u32(b, &state->maxidx)) != 0 || - (r = sshbuf_get_u8(b, &state->allow_update)) != 0) - return r; - break; - case SSHKEY_SERIALIZE_STATE: - if ((r = sshkey_xmss_deserialize_state(k, b)) != 0) - return r; - break; - case SSHKEY_SERIALIZE_FULL: - if ((r = sshkey_xmss_deserialize_enc_key(k, b)) != 0 || - (r = sshkey_xmss_deserialize_state(k, b)) != 0) - return r; - break; - default: - r = SSH_ERR_INVALID_FORMAT; - break; - } - return r; -} - -int -sshkey_xmss_encrypt_state(const struct sshkey *k, struct sshbuf *b, - struct sshbuf **retp) -{ - struct ssh_xmss_state *state = k->xmss_state; - struct sshbuf *encrypted = NULL, *encoded = NULL, *padded = NULL; - struct sshcipher_ctx *ciphercontext = NULL; - const struct sshcipher *cipher; - u_char *cp, *key, *iv = NULL; - size_t i, keylen, ivlen, blocksize, authlen, encrypted_len, aadlen; - int r = SSH_ERR_INTERNAL_ERROR; - - if (retp != NULL) - *retp = NULL; - if (state == NULL || - state->enc_keyiv == NULL || - state->enc_ciphername == NULL) - return SSH_ERR_INTERNAL_ERROR; - if ((cipher = cipher_by_name(state->enc_ciphername)) == NULL) { - r = SSH_ERR_INTERNAL_ERROR; - goto out; - } - blocksize = cipher_blocksize(cipher); - keylen = cipher_keylen(cipher); - ivlen = cipher_ivlen(cipher); - authlen = cipher_authlen(cipher); - if (state->enc_keyiv_len != keylen + ivlen) { - r = SSH_ERR_INVALID_FORMAT; - goto out; - } - key = state->enc_keyiv; - if ((encrypted = sshbuf_new()) == NULL || - (encoded = sshbuf_new()) == NULL || - (padded = sshbuf_new()) == NULL || - (iv = malloc(ivlen)) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto out; - } - - /* replace first 4 bytes of IV with index to ensure uniqueness */ - memcpy(iv, key + keylen, ivlen); - POKE_U32(iv, state->idx); - - if ((r = sshbuf_put(encoded, XMSS_MAGIC, sizeof(XMSS_MAGIC))) != 0 || - (r = sshbuf_put_u32(encoded, state->idx)) != 0) - goto out; - - /* padded state will be encrypted */ - if ((r = sshbuf_putb(padded, b)) != 0) - goto out; - i = 0; - while (sshbuf_len(padded) % blocksize) { - if ((r = sshbuf_put_u8(padded, ++i & 0xff)) != 0) - goto out; - } - encrypted_len = sshbuf_len(padded); - - /* header including the length of state is used as AAD */ - if ((r = sshbuf_put_u32(encoded, encrypted_len)) != 0) - goto out; - aadlen = sshbuf_len(encoded); - - /* concat header and state */ - if ((r = sshbuf_putb(encoded, padded)) != 0) - goto out; - - /* reserve space for encryption of encoded data plus auth tag */ - /* encrypt at offset addlen */ - if ((r = sshbuf_reserve(encrypted, - encrypted_len + aadlen + authlen, &cp)) != 0 || - (r = cipher_init(&ciphercontext, cipher, key, keylen, - iv, ivlen, 1)) != 0 || - (r = cipher_crypt(ciphercontext, 0, cp, sshbuf_ptr(encoded), - encrypted_len, aadlen, authlen)) != 0) - goto out; - - /* success */ - r = 0; - out: - if (retp != NULL) { - *retp = encrypted; - encrypted = NULL; - } - sshbuf_free(padded); - sshbuf_free(encoded); - sshbuf_free(encrypted); - cipher_free(ciphercontext); - free(iv); - return r; -} - -int -sshkey_xmss_decrypt_state(const struct sshkey *k, struct sshbuf *encoded, - struct sshbuf **retp) -{ - struct ssh_xmss_state *state = k->xmss_state; - struct sshbuf *copy = NULL, *decrypted = NULL; - struct sshcipher_ctx *ciphercontext = NULL; - const struct sshcipher *cipher = NULL; - u_char *key, *iv = NULL, *dp; - size_t keylen, ivlen, authlen, aadlen; - u_int blocksize, encrypted_len, index; - int r = SSH_ERR_INTERNAL_ERROR; - - if (retp != NULL) - *retp = NULL; - if (state == NULL || - state->enc_keyiv == NULL || - state->enc_ciphername == NULL) - return SSH_ERR_INTERNAL_ERROR; - if ((cipher = cipher_by_name(state->enc_ciphername)) == NULL) { - r = SSH_ERR_INVALID_FORMAT; - goto out; - } - blocksize = cipher_blocksize(cipher); - keylen = cipher_keylen(cipher); - ivlen = cipher_ivlen(cipher); - authlen = cipher_authlen(cipher); - if (state->enc_keyiv_len != keylen + ivlen) { - r = SSH_ERR_INTERNAL_ERROR; - goto out; - } - key = state->enc_keyiv; - - if ((copy = sshbuf_fromb(encoded)) == NULL || - (decrypted = sshbuf_new()) == NULL || - (iv = malloc(ivlen)) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto out; - } - - /* check magic */ - if (sshbuf_len(encoded) < sizeof(XMSS_MAGIC) || - memcmp(sshbuf_ptr(encoded), XMSS_MAGIC, sizeof(XMSS_MAGIC))) { - r = SSH_ERR_INVALID_FORMAT; - goto out; - } - /* parse public portion */ - if ((r = sshbuf_consume(encoded, sizeof(XMSS_MAGIC))) != 0 || - (r = sshbuf_get_u32(encoded, &index)) != 0 || - (r = sshbuf_get_u32(encoded, &encrypted_len)) != 0) - goto out; - - /* check size of encrypted key blob */ - if (encrypted_len < blocksize || (encrypted_len % blocksize) != 0) { - r = SSH_ERR_INVALID_FORMAT; - goto out; - } - /* check that an appropriate amount of auth data is present */ - if (sshbuf_len(encoded) < authlen || - sshbuf_len(encoded) - authlen < encrypted_len) { - r = SSH_ERR_INVALID_FORMAT; - goto out; - } - - aadlen = sshbuf_len(copy) - sshbuf_len(encoded); - - /* replace first 4 bytes of IV with index to ensure uniqueness */ - memcpy(iv, key + keylen, ivlen); - POKE_U32(iv, index); - - /* decrypt private state of key */ - if ((r = sshbuf_reserve(decrypted, aadlen + encrypted_len, &dp)) != 0 || - (r = cipher_init(&ciphercontext, cipher, key, keylen, - iv, ivlen, 0)) != 0 || - (r = cipher_crypt(ciphercontext, 0, dp, sshbuf_ptr(copy), - encrypted_len, aadlen, authlen)) != 0) - goto out; - - /* there should be no trailing data */ - if ((r = sshbuf_consume(encoded, encrypted_len + authlen)) != 0) - goto out; - if (sshbuf_len(encoded) != 0) { - r = SSH_ERR_INVALID_FORMAT; - goto out; - } - - /* remove AAD */ - if ((r = sshbuf_consume(decrypted, aadlen)) != 0) - goto out; - /* XXX encrypted includes unchecked padding */ - - /* success */ - r = 0; - if (retp != NULL) { - *retp = decrypted; - decrypted = NULL; - } - out: - cipher_free(ciphercontext); - sshbuf_free(copy); - sshbuf_free(decrypted); - free(iv); - return r; -} - -u_int32_t -sshkey_xmss_signatures_left(const struct sshkey *k) -{ - struct ssh_xmss_state *state = k->xmss_state; - u_int32_t idx; - - if (sshkey_type_plain(k->type) == KEY_XMSS && state && - state->maxidx) { - idx = k->xmss_sk ? PEEK_U32(k->xmss_sk) : state->idx; - if (idx < state->maxidx) - return state->maxidx - idx; - } - return 0; -} - -int -sshkey_xmss_enable_maxsign(struct sshkey *k, u_int32_t maxsign) -{ - struct ssh_xmss_state *state = k->xmss_state; - - if (sshkey_type_plain(k->type) != KEY_XMSS) - return SSH_ERR_INVALID_ARGUMENT; - if (maxsign == 0) - return 0; - if (state->idx + maxsign < state->idx) - return SSH_ERR_INVALID_ARGUMENT; - state->maxidx = state->idx + maxsign; - return 0; -} -#endif /* WITH_XMSS */ diff --git a/sshkey-xmss.h b/sshkey-xmss.h deleted file mode 100644 index ab8b9c9..0000000 --- a/sshkey-xmss.h +++ /dev/null @@ -1,56 +0,0 @@ -/* $OpenBSD: sshkey-xmss.h,v 1.4 2022/10/28 00:39:29 djm Exp $ */ -/* - * Copyright (c) 2017 Markus Friedl. 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef SSHKEY_XMSS_H -#define SSHKEY_XMSS_H - -#define XMSS_SHA2_256_W16_H10_NAME "XMSS_SHA2-256_W16_H10" -#define XMSS_SHA2_256_W16_H16_NAME "XMSS_SHA2-256_W16_H16" -#define XMSS_SHA2_256_W16_H20_NAME "XMSS_SHA2-256_W16_H20" -#define XMSS_DEFAULT_NAME XMSS_SHA2_256_W16_H10_NAME - -size_t sshkey_xmss_pklen(const struct sshkey *); -size_t sshkey_xmss_sklen(const struct sshkey *); -int sshkey_xmss_init(struct sshkey *, const char *); -void sshkey_xmss_free_state(struct sshkey *); -int sshkey_xmss_generate_private_key(struct sshkey *, int); -int sshkey_xmss_serialize_state(const struct sshkey *, struct sshbuf *); -int sshkey_xmss_serialize_state_opt(const struct sshkey *, struct sshbuf *, - enum sshkey_serialize_rep); -int sshkey_xmss_serialize_pk_info(const struct sshkey *, struct sshbuf *, - enum sshkey_serialize_rep); -int sshkey_xmss_deserialize_state(struct sshkey *, struct sshbuf *); -int sshkey_xmss_deserialize_state_opt(struct sshkey *, struct sshbuf *); -int sshkey_xmss_deserialize_pk_info(struct sshkey *, struct sshbuf *); - -int sshkey_xmss_siglen(const struct sshkey *, size_t *); -void *sshkey_xmss_params(const struct sshkey *); -void *sshkey_xmss_bds_state(const struct sshkey *); -int sshkey_xmss_get_state(const struct sshkey *, int); -int sshkey_xmss_enable_maxsign(struct sshkey *, u_int32_t); -int sshkey_xmss_forward_state(const struct sshkey *, u_int32_t); -int sshkey_xmss_update_state(const struct sshkey *, int); -u_int32_t sshkey_xmss_signatures_left(const struct sshkey *); - -#endif /* SSHKEY_XMSS_H */ diff --git a/sshkey.c b/sshkey.c index 1db8378..59d1453 100644 --- a/sshkey.c +++ b/sshkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshkey.c,v 1.146 2024/09/04 05:33:34 djm Exp $ */ +/* $OpenBSD: sshkey.c,v 1.161 2026/02/06 22:59:18 dtucker Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * Copyright (c) 2008 Alexander von Gernler. All rights reserved. @@ -32,6 +32,7 @@ #include #ifdef WITH_OPENSSL +#include #include #include #include @@ -46,9 +47,7 @@ #include #include #include -#ifdef HAVE_UTIL_H #include -#endif /* HAVE_UTIL_H */ #include "ssh2.h" #include "ssherr.h" @@ -60,11 +59,7 @@ #include "sshkey.h" #include "match.h" #include "ssh-sk.h" - -#ifdef WITH_XMSS -#include "sshkey-xmss.h" -#include "xmss_fast.h" -#endif +#include "ssh-pkcs11.h" #include "openbsd-compat/openssl-compat.h" @@ -79,9 +74,6 @@ #define DEFAULT_CIPHERNAME "aes256-ctr" #define DEFAULT_ROUNDS 24 -/* Version identification string for SSH v1 identity files. */ -#define LEGACY_BEGIN "SSH PRIVATE KEY FILE FORMAT 1.1\n" - /* * Constants relating to "shielding" support; protection of keys expected * to remain in memory for long durations @@ -90,8 +82,6 @@ #define SSHKEY_SHIELD_CIPHER "aes256-ctr" /* XXX want AES-EME* */ #define SSHKEY_SHIELD_PREKEY_HASH SSH_DIGEST_SHA512 -int sshkey_private_serialize_opt(struct sshkey *key, - struct sshbuf *buf, enum sshkey_serialize_rep); static int sshkey_from_blob_internal(struct sshbuf *buf, struct sshkey **keyp, int allow_cert); @@ -106,6 +96,7 @@ extern const struct sshkey_impl sshkey_ed25519_sk_cert_impl; extern const struct sshkey_impl sshkey_ecdsa_sk_impl; extern const struct sshkey_impl sshkey_ecdsa_sk_cert_impl; extern const struct sshkey_impl sshkey_ecdsa_sk_webauthn_impl; +extern const struct sshkey_impl sshkey_ecdsa_sk_webauthn_cert_impl; # endif /* ENABLE_SK */ extern const struct sshkey_impl sshkey_ecdsa_nistp256_impl; extern const struct sshkey_impl sshkey_ecdsa_nistp256_cert_impl; @@ -122,15 +113,7 @@ extern const struct sshkey_impl sshkey_rsa_sha256_impl; extern const struct sshkey_impl sshkey_rsa_sha256_cert_impl; extern const struct sshkey_impl sshkey_rsa_sha512_impl; extern const struct sshkey_impl sshkey_rsa_sha512_cert_impl; -# ifdef WITH_DSA -extern const struct sshkey_impl sshkey_dss_impl; -extern const struct sshkey_impl sshkey_dsa_cert_impl; -# endif #endif /* WITH_OPENSSL */ -#ifdef WITH_XMSS -extern const struct sshkey_impl sshkey_xmss_impl; -extern const struct sshkey_impl sshkey_xmss_cert_impl; -#endif const struct sshkey_impl * const keyimpls[] = { &sshkey_ed25519_impl, @@ -153,12 +136,9 @@ const struct sshkey_impl * const keyimpls[] = { &sshkey_ecdsa_sk_impl, &sshkey_ecdsa_sk_cert_impl, &sshkey_ecdsa_sk_webauthn_impl, + &sshkey_ecdsa_sk_webauthn_cert_impl, # endif /* ENABLE_SK */ # endif /* OPENSSL_HAS_ECC */ -# ifdef WITH_DSA - &sshkey_dss_impl, - &sshkey_dsa_cert_impl, -# endif &sshkey_rsa_impl, &sshkey_rsa_cert_impl, &sshkey_rsa_sha256_impl, @@ -166,10 +146,6 @@ const struct sshkey_impl * const keyimpls[] = { &sshkey_rsa_sha512_impl, &sshkey_rsa_sha512_cert_impl, #endif /* WITH_OPENSSL */ -#ifdef WITH_XMSS - &sshkey_xmss_impl, - &sshkey_xmss_cert_impl, -#endif NULL }; @@ -326,6 +302,17 @@ sshkey_match_keyname_to_sigalgs(const char *keyname, const char *sigalgs) sigalgs, 0) == 1 || match_pattern_list("rsa-sha2-512-cert-v01@openssh.com", sigalgs, 0) == 1; + } else if (ktype == KEY_ECDSA_SK) { + return match_pattern_list("sk-ecdsa-sha2-nistp256@openssh.com", + sigalgs, 0) == 1 || match_pattern_list( + "webauthn-sk-ecdsa-sha2-nistp256@openssh.com", + sigalgs, 0) == 1; + } else if (ktype == KEY_ECDSA_SK_CERT) { + return match_pattern_list( + "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com", + sigalgs, 0) == 1 || match_pattern_list( + "webauthn-sk-ecdsa-sha2-nistp256-cert-v01@openssh.com", + sigalgs, 0) == 1; } else return match_pattern_list(keyname, sigalgs, 0) == 1; } @@ -333,9 +320,10 @@ sshkey_match_keyname_to_sigalgs(const char *keyname, const char *sigalgs) char * sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) { - char *tmp, *ret = NULL; - size_t i, nlen, rlen = 0; + char *ret = NULL; + size_t i; const struct sshkey_impl *impl; + char sep_str[2] = {sep, '\0'}; for (i = 0; keyimpls[i] != NULL; i++) { impl = keyimpls[i]; @@ -345,16 +333,7 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) continue; if ((certs_only && !impl->cert) || (plain_only && impl->cert)) continue; - if (ret != NULL) - ret[rlen++] = sep; - nlen = strlen(impl->name); - if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) { - free(ret); - return NULL; - } - ret = tmp; - memcpy(ret + rlen, impl->name, nlen + 1); - rlen += nlen; + xextendf(&ret, sep_str, "%s", impl->name); } return ret; } @@ -454,8 +433,6 @@ sshkey_type_plain(int type) switch (type) { case KEY_RSA_CERT: return KEY_RSA; - case KEY_DSA_CERT: - return KEY_DSA; case KEY_ECDSA_CERT: return KEY_ECDSA; case KEY_ECDSA_SK_CERT: @@ -464,8 +441,6 @@ sshkey_type_plain(int type) return KEY_ED25519; case KEY_ED25519_SK_CERT: return KEY_ED25519_SK; - case KEY_XMSS_CERT: - return KEY_XMSS; default: return type; } @@ -478,8 +453,6 @@ sshkey_type_certified(int type) switch (type) { case KEY_RSA: return KEY_RSA_CERT; - case KEY_DSA: - return KEY_DSA_CERT; case KEY_ECDSA: return KEY_ECDSA_CERT; case KEY_ECDSA_SK: @@ -488,8 +461,6 @@ sshkey_type_certified(int type) return KEY_ED25519_CERT; case KEY_ED25519_SK: return KEY_ED25519_SK_CERT; - case KEY_XMSS: - return KEY_XMSS_CERT; default: return -1; } @@ -765,6 +736,7 @@ sshkey_sk_cleanup(struct sshkey *k) static int sshkey_prekey_alloc(u_char **prekeyp, size_t len) { +#if defined(HAVE_MMAP) && defined(MAP_ANON) && defined(MAP_PRIVATE) u_char *prekey; *prekeyp = NULL; @@ -775,15 +747,22 @@ sshkey_prekey_alloc(u_char **prekeyp, size_t len) (void)madvise(prekey, len, MADV_DONTDUMP); #endif *prekeyp = prekey; +#else + *prekeyp = calloc(1, len); +#endif /* HAVE_MMAP et al */ return 0; } static void sshkey_prekey_free(void *prekey, size_t len) { +#if defined(HAVE_MMAP) && defined(MAP_ANON) && defined(MAP_PRIVATE) if (prekey == NULL) return; munmap(prekey, len); +#else + free(prekey); +#endif /* HAVE_MMAP et al */ } static void @@ -793,6 +772,8 @@ sshkey_free_contents(struct sshkey *k) if (k == NULL) return; + if ((k->flags & SSHKEY_FLAG_EXT) != 0) + pkcs11_key_free(k); if ((impl = sshkey_impl_from_type(k->type)) != NULL && impl->funcs->cleanup != NULL) impl->funcs->cleanup(k); @@ -915,16 +896,16 @@ sshkey_putb(const struct sshkey *key, struct sshbuf *b) return to_blob_buf(key, b, 0, SSHKEY_SERIALIZE_DEFAULT); } -int -sshkey_puts_opts(const struct sshkey *key, struct sshbuf *b, - enum sshkey_serialize_rep opts) +static int +sshkey_puts_opts_internal(const struct sshkey *key, struct sshbuf *b, + enum sshkey_serialize_rep opts, int force_plain) { struct sshbuf *tmp; int r; if ((tmp = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; - r = to_blob_buf(key, tmp, 0, opts); + r = to_blob_buf(key, tmp, force_plain, opts); if (r == 0) r = sshbuf_put_stringb(b, tmp); sshbuf_free(tmp); @@ -934,7 +915,7 @@ sshkey_puts_opts(const struct sshkey *key, struct sshbuf *b, int sshkey_puts(const struct sshkey *key, struct sshbuf *b) { - return sshkey_puts_opts(key, b, SSHKEY_SERIALIZE_DEFAULT); + return sshkey_puts_opts_internal(key, b, SSHKEY_SERIALIZE_DEFAULT, 0); } int @@ -943,6 +924,12 @@ sshkey_putb_plain(const struct sshkey *key, struct sshbuf *b) return to_blob_buf(key, b, 1, SSHKEY_SERIALIZE_DEFAULT); } +int +sshkey_puts_plain(const struct sshkey *key, struct sshbuf *b) +{ + return sshkey_puts_opts_internal(key, b, SSHKEY_SERIALIZE_DEFAULT, 1); +} + static int to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp, int force_plain, enum sshkey_serialize_rep opts) @@ -1690,8 +1677,7 @@ sshkey_shield_private(struct sshkey *k) } if (sshkey_is_shielded(k) && (r = sshkey_unshield_private(k)) != 0) goto out; - if ((r = sshkey_private_serialize_opt(k, prvbuf, - SSHKEY_SERIALIZE_SHIELD)) != 0) + if ((r = sshkey_private_serialize(k, prvbuf)) != 0) goto out; /* pad to cipher blocksize */ i = 0; @@ -2215,6 +2201,9 @@ sshkey_sign(struct sshkey *key, if (sshkey_is_sk(key)) { r = sshsk_sign(sk_provider, key, sigp, lenp, data, datalen, compat, sk_pin); + } else if ((key->flags & SSHKEY_FLAG_EXT) != 0) { + r = pkcs11_sign(key, sigp, lenp, data, datalen, + alg, sk_provider, sk_pin, compat); } else { if (impl->funcs->sign == NULL) r = SSH_ERR_SIGN_ALG_UNSUPPORTED; @@ -2229,7 +2218,7 @@ sshkey_sign(struct sshkey *key, } /* - * ssh_key_verify returns 0 for a correct signature and < 0 on error. + * ssh_key_verify returns 0 for a correct signature and < 0 on error. * If "alg" specified, then the signature must use that algorithm. */ int @@ -2410,8 +2399,8 @@ sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg, int sshkey_cert_check_authority(const struct sshkey *k, - int want_host, int require_principal, int wildcard_pattern, - uint64_t verify_time, const char *name, const char **reason) + int want_host, int wildcard_pattern, uint64_t verify_time, + const char *name, const char **reason) { u_int i, principal_matches; @@ -2441,37 +2430,36 @@ sshkey_cert_check_authority(const struct sshkey *k, return SSH_ERR_KEY_CERT_INVALID; } if (k->cert->nprincipals == 0) { - if (require_principal) { - *reason = "Certificate lacks principal list"; - return SSH_ERR_KEY_CERT_INVALID; - } - } else if (name != NULL) { - principal_matches = 0; - for (i = 0; i < k->cert->nprincipals; i++) { - if (wildcard_pattern) { - if (match_pattern(k->cert->principals[i], - name)) { - principal_matches = 1; - break; - } - } else if (strcmp(name, k->cert->principals[i]) == 0) { + *reason = "Certificate lacks principal list"; + return SSH_ERR_KEY_CERT_INVALID; + } + if (name == NULL) + return 0; /* principal matching not requested */ + + principal_matches = 0; + for (i = 0; i < k->cert->nprincipals; i++) { + if (wildcard_pattern) { + if (match_pattern(name, k->cert->principals[i])) { principal_matches = 1; break; } - } - if (!principal_matches) { - *reason = "Certificate invalid: name is not a listed " - "principal"; - return SSH_ERR_KEY_CERT_INVALID; + } else if (strcmp(name, k->cert->principals[i]) == 0) { + principal_matches = 1; + break; } } + if (!principal_matches) { + *reason = "Certificate invalid: name is not a listed " + "principal"; + return SSH_ERR_KEY_CERT_INVALID; + } return 0; } int sshkey_cert_check_authority_now(const struct sshkey *k, - int want_host, int require_principal, int wildcard_pattern, - const char *name, const char **reason) + int want_host, int wildcard_pattern, const char *name, + const char **reason) { time_t now; @@ -2480,19 +2468,17 @@ sshkey_cert_check_authority_now(const struct sshkey *k, *reason = "Certificate invalid: not yet valid"; return SSH_ERR_KEY_CERT_INVALID; } - return sshkey_cert_check_authority(k, want_host, require_principal, - wildcard_pattern, (uint64_t)now, name, reason); + return sshkey_cert_check_authority(k, want_host, wildcard_pattern, + (uint64_t)now, name, reason); } int sshkey_cert_check_host(const struct sshkey *key, const char *host, - int wildcard_principals, const char *ca_sign_algorithms, - const char **reason) + const char *ca_sign_algorithms, const char **reason) { int r; - if ((r = sshkey_cert_check_authority_now(key, 1, 0, wildcard_principals, - host, reason)) != 0) + if ((r = sshkey_cert_check_authority_now(key, 1, 1, host, reason)) != 0) return r; if (sshbuf_len(key->cert->critical) != 0) { *reason = "Certificate contains unsupported critical options"; @@ -2546,7 +2532,7 @@ sshkey_serialize_private_sk(const struct sshkey *key, struct sshbuf *b) return 0; } -int +static int sshkey_private_serialize_opt(struct sshkey *key, struct sshbuf *buf, enum sshkey_serialize_rep opts) { @@ -2597,6 +2583,7 @@ sshkey_private_serialize(struct sshkey *key, struct sshbuf *b) SSHKEY_SERIALIZE_DEFAULT); } + /* Shared deserialization of FIDO private key components */ int sshkey_private_deserialize_sk(struct sshbuf *buf, struct sshkey *k) @@ -2656,7 +2643,6 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) expect_ed25519_pk = k->ed25519_pk; k->sk_application = NULL; k->ed25519_pk = NULL; - /* XXX xmss too or refactor */ } else { if ((k = sshkey_new(type)) == NULL) { r = SSH_ERR_ALLOC_FAIL; @@ -2670,7 +2656,6 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) if ((r = impl->funcs->deserialize_private(tname, buf, k)) != 0) goto out; - /* XXX xmss too or refactor */ if ((expect_sk_application != NULL && (k->sk_application == NULL || strcmp(expect_sk_application, k->sk_application) != 0)) || (expect_ed25519_pk != NULL && (k->ed25519_pk == NULL || @@ -2697,73 +2682,54 @@ int sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) { EC_POINT *nq = NULL; - BIGNUM *order = NULL, *x = NULL, *y = NULL, *tmp = NULL; + BIGNUM *order = NULL, *cofactor = NULL; int ret = SSH_ERR_KEY_INVALID_EC_VALUE; /* * NB. This assumes OpenSSL has already verified that the public - * point lies on the curve. This is done by EC_POINT_oct2point() - * implicitly calling EC_POINT_is_on_curve(). If this code is ever - * reachable with public points not unmarshalled using - * EC_POINT_oct2point then the caller will need to explicitly check. - */ - - /* - * We shouldn't ever hit this case because bignum_get_ecpoint() - * refuses to load GF2m points. + * point lies on the curve and that its coordinates are in [0, p). + * This is done by EC_POINT_oct2point() on at least OpenSSL >= 1.1, + * LibreSSL and BoringSSL. */ - if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != - NID_X9_62_prime_field) - goto out; /* Q != infinity */ if (EC_POINT_is_at_infinity(group, public)) goto out; - if ((x = BN_new()) == NULL || - (y = BN_new()) == NULL || - (order = BN_new()) == NULL || - (tmp = BN_new()) == NULL) { + if ((cofactor = BN_new()) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } - - /* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */ - if (EC_GROUP_get_order(group, order, NULL) != 1 || - EC_POINT_get_affine_coordinates_GFp(group, public, - x, y, NULL) != 1) { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } - if (BN_num_bits(x) <= BN_num_bits(order) / 2 || - BN_num_bits(y) <= BN_num_bits(order) / 2) + if (EC_GROUP_get_cofactor(group, cofactor, NULL) != 1) goto out; - /* nQ == infinity (n == order of subgroup) */ - if ((nq = EC_POINT_new(group)) == NULL) { - ret = SSH_ERR_ALLOC_FAIL; - goto out; - } - if (EC_POINT_mul(group, nq, NULL, public, order, NULL) != 1) { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; + /* + * Verify nQ == infinity (n == order of subgroup) + * This check may be skipped for curves with cofactor 1, as per + * NIST SP 800-56A, 5.6.2.3. + */ + if (!BN_is_one(cofactor)) { + if ((order = BN_new()) == NULL) { + ret = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((nq = EC_POINT_new(group)) == NULL) { + ret = SSH_ERR_ALLOC_FAIL; + goto out; + } + if (EC_POINT_mul(group, nq, NULL, public, order, NULL) != 1) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + if (EC_POINT_is_at_infinity(group, nq) != 1) + goto out; } - if (EC_POINT_is_at_infinity(group, nq) != 1) - goto out; - /* x < order - 1, y < order - 1 */ - if (!BN_sub(tmp, order, BN_value_one())) { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } - if (BN_cmp(x, tmp) >= 0 || BN_cmp(y, tmp) >= 0) - goto out; + /* success */ ret = 0; out: - BN_clear_free(x); - BN_clear_free(y); + BN_clear_free(cofactor); BN_clear_free(order); - BN_clear_free(tmp); EC_POINT_free(nq); return ret; } @@ -2815,14 +2781,8 @@ sshkey_dump_ec_point(const EC_GROUP *group, const EC_POINT *point) fprintf(stderr, "%s: BN_new failed\n", __func__); goto out; } - if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != - NID_X9_62_prime_field) { - fprintf(stderr, "%s: group is not a prime field\n", __func__); - goto out; - } - if (EC_POINT_get_affine_coordinates_GFp(group, point, - x, y, NULL) != 1) { - fprintf(stderr, "%s: EC_POINT_get_affine_coordinates_GFp\n", + if (EC_POINT_get_affine_coordinates(group, point, x, y, NULL) != 1) { + fprintf(stderr, "%s: EC_POINT_get_affine_coordinates\n", __func__); goto out; } @@ -2930,8 +2890,7 @@ sshkey_private_to_blob2(struct sshkey *prv, struct sshbuf *blob, goto out; /* append private key and comment*/ - if ((r = sshkey_private_serialize_opt(prv, encrypted, - SSHKEY_SERIALIZE_FULL)) != 0 || + if ((r = sshkey_private_serialize(prv, encrypted)) != 0 || (r = sshbuf_put_cstring(encrypted, comment)) != 0) goto out; @@ -3338,20 +3297,6 @@ sshkey_private_to_blob_pem_pkcs8(struct sshkey *key, struct sshbuf *buf, goto out; switch (key->type) { -#ifdef WITH_DSA - case KEY_DSA: - if (format == SSHKEY_PRIVATE_PEM) { - success = PEM_write_bio_DSAPrivateKey(bio, key->dsa, - cipher, passphrase, len, NULL, NULL); - } else { - if ((pkey = EVP_PKEY_new()) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto out; - } - success = EVP_PKEY_set1_DSA(pkey, key->dsa); - } - break; -#endif #ifdef OPENSSL_HAS_ECC case KEY_ECDSA: if (format == SSHKEY_PRIVATE_PEM) { @@ -3376,6 +3321,19 @@ sshkey_private_to_blob_pem_pkcs8(struct sshkey *key, struct sshbuf *buf, success = 1; } break; +#ifdef OPENSSL_HAS_ED25519 + case KEY_ED25519: + if (format == SSHKEY_PRIVATE_PEM) { + r = SSH_ERR_INVALID_FORMAT; + goto out; + } else { + pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519, + NULL, key->ed25519_sk, + ED25519_SK_SZ - ED25519_PK_SZ); + success = pkey != NULL; + } + break; +#endif default: success = 0; break; @@ -3419,16 +3377,14 @@ sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, { switch (key->type) { #ifdef WITH_OPENSSL - case KEY_DSA: case KEY_ECDSA: case KEY_RSA: + case KEY_ED25519: break; /* see below */ -#endif /* WITH_OPENSSL */ +#else /* WITH_OPENSSL */ case KEY_ED25519: +#endif /* WITH_OPENSSL */ case KEY_ED25519_SK: -#ifdef WITH_XMSS - case KEY_XMSS: -#endif /* WITH_XMSS */ #ifdef WITH_OPENSSL case KEY_ECDSA_SK: #endif /* WITH_OPENSSL */ @@ -3594,19 +3550,6 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, prv->pkey = pk; if ((r = sshkey_check_rsa_length(prv, 0)) != 0) goto out; -#ifdef WITH_DSA - } else if (EVP_PKEY_base_id(pk) == EVP_PKEY_DSA && - (type == KEY_UNSPEC || type == KEY_DSA)) { - if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto out; - } - prv->dsa = EVP_PKEY_get1_DSA(pk); - prv->type = KEY_DSA; -#ifdef DEBUG_PK - DSA_print_fp(stderr, prv->dsa, 8); -#endif -#endif #ifdef OPENSSL_HAS_ECC } else if (EVP_PKEY_base_id(pk) == EVP_PKEY_EC && (type == KEY_UNSPEC || type == KEY_ECDSA)) { @@ -3703,24 +3646,16 @@ sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, if (commentp != NULL) *commentp = NULL; - switch (type) { - case KEY_XMSS: - /* No fallback for new-format-only keys */ - return sshkey_parse_private2(blob, type, passphrase, - keyp, commentp); - default: - r = sshkey_parse_private2(blob, type, passphrase, keyp, - commentp); - /* Only fallback to PEM parser if a format error occurred. */ - if (r != SSH_ERR_INVALID_FORMAT) - return r; + r = sshkey_parse_private2(blob, type, passphrase, keyp, commentp); + /* Only fallback to PEM parser if a format error occurred. */ + if (r != SSH_ERR_INVALID_FORMAT) + return r; #ifdef WITH_OPENSSL - return sshkey_parse_private_pem_fileblob(blob, type, - passphrase, keyp); + return sshkey_parse_private_pem_fileblob(blob, type, + passphrase, keyp); #else - return SSH_ERR_INVALID_FORMAT; + return SSH_ERR_INVALID_FORMAT; #endif /* WITH_OPENSSL */ - } } int @@ -3755,90 +3690,3 @@ sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf *blob, int type, return r; return 0; } - -#ifdef WITH_XMSS -/* - * serialize the key with the current state and forward the state - * maxsign times. - */ -int -sshkey_private_serialize_maxsign(struct sshkey *k, struct sshbuf *b, - u_int32_t maxsign, int printerror) -{ - int r, rupdate; - - if (maxsign == 0 || - sshkey_type_plain(k->type) != KEY_XMSS) - return sshkey_private_serialize_opt(k, b, - SSHKEY_SERIALIZE_DEFAULT); - if ((r = sshkey_xmss_get_state(k, printerror)) != 0 || - (r = sshkey_private_serialize_opt(k, b, - SSHKEY_SERIALIZE_STATE)) != 0 || - (r = sshkey_xmss_forward_state(k, maxsign)) != 0) - goto out; - r = 0; -out: - if ((rupdate = sshkey_xmss_update_state(k, printerror)) != 0) { - if (r == 0) - r = rupdate; - } - return r; -} - -u_int32_t -sshkey_signatures_left(const struct sshkey *k) -{ - if (sshkey_type_plain(k->type) == KEY_XMSS) - return sshkey_xmss_signatures_left(k); - return 0; -} - -int -sshkey_enable_maxsign(struct sshkey *k, u_int32_t maxsign) -{ - if (sshkey_type_plain(k->type) != KEY_XMSS) - return SSH_ERR_INVALID_ARGUMENT; - return sshkey_xmss_enable_maxsign(k, maxsign); -} - -int -sshkey_set_filename(struct sshkey *k, const char *filename) -{ - if (k == NULL) - return SSH_ERR_INVALID_ARGUMENT; - if (sshkey_type_plain(k->type) != KEY_XMSS) - return 0; - if (filename == NULL) - return SSH_ERR_INVALID_ARGUMENT; - if ((k->xmss_filename = strdup(filename)) == NULL) - return SSH_ERR_ALLOC_FAIL; - return 0; -} -#else -int -sshkey_private_serialize_maxsign(struct sshkey *k, struct sshbuf *b, - u_int32_t maxsign, int printerror) -{ - return sshkey_private_serialize_opt(k, b, SSHKEY_SERIALIZE_DEFAULT); -} - -u_int32_t -sshkey_signatures_left(const struct sshkey *k) -{ - return 0; -} - -int -sshkey_enable_maxsign(struct sshkey *k, u_int32_t maxsign) -{ - return SSH_ERR_INVALID_ARGUMENT; -} - -int -sshkey_set_filename(struct sshkey *k, const char *filename) -{ - if (k == NULL) - return SSH_ERR_INVALID_ARGUMENT; - return 0; -} -#endif /* WITH_XMSS */ diff --git a/sshkey.h b/sshkey.h index d0cdea0..a9cdfcd 100644 --- a/sshkey.h +++ b/sshkey.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshkey.h,v 1.65 2024/09/04 05:33:34 djm Exp $ */ +/* $OpenBSD: sshkey.h,v 1.73 2026/03/03 09:57:26 dtucker Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -30,7 +30,6 @@ #ifdef WITH_OPENSSL #include -#include #include # ifdef OPENSSL_HAS_ECC # include @@ -44,7 +43,6 @@ #else /* WITH_OPENSSL */ # define BIGNUM void # define RSA void -# define DSA void # define EC_KEY void # define EC_GROUP void # define EC_POINT void @@ -60,15 +58,11 @@ struct sshbuf; /* Key types */ enum sshkey_types { KEY_RSA, - KEY_DSA, KEY_ECDSA, KEY_ED25519, KEY_RSA_CERT, - KEY_DSA_CERT, KEY_ECDSA_CERT, KEY_ED25519_CERT, - KEY_XMSS, - KEY_XMSS_CERT, KEY_ECDSA_SK, KEY_ECDSA_SK_CERT, KEY_ED25519_SK, @@ -91,10 +85,6 @@ enum sshkey_fp_rep { /* Private key serialisation formats, used on the wire */ enum sshkey_serialize_rep { SSHKEY_SERIALIZE_DEFAULT = 0, - SSHKEY_SERIALIZE_STATE = 1, /* only state is serialized */ - SSHKEY_SERIALIZE_FULL = 2, /* include keys for saving to disk */ - SSHKEY_SERIALIZE_SHIELD = 3, /* everything, for encrypting in ram */ - SSHKEY_SERIALIZE_INFO = 254, /* minimal information */ }; /* Private key disk formats */ @@ -108,27 +98,25 @@ enum sshkey_private_format { #define SSHKEY_FLAG_EXT 0x0001 #define SSHKEY_CERT_MAX_PRINCIPALS 256 -/* XXX opaquify? */ +/* XXX opacify? */ struct sshkey_cert { struct sshbuf *certblob; /* Kept around for use on wire */ u_int type; /* SSH2_CERT_TYPE_USER or SSH2_CERT_TYPE_HOST */ - u_int64_t serial; + uint64_t serial; char *key_id; u_int nprincipals; char **principals; - u_int64_t valid_after, valid_before; + uint64_t valid_after, valid_before; struct sshbuf *critical; struct sshbuf *extensions; struct sshkey *signature_key; char *signature_type; }; -/* XXX opaquify? */ +/* XXX opacify? */ struct sshkey { int type; int flags; - /* KEY_DSA */ - DSA *dsa; /* KEY_ECDSA and KEY_ECDSA_SK */ int ecdsa_nid; /* NID of curve */ /* libcrypto-backed keys */ @@ -136,12 +124,6 @@ struct sshkey { /* KEY_ED25519 and KEY_ED25519_SK */ u_char *ed25519_sk; u_char *ed25519_pk; - /* KEY_XMSS */ - char *xmss_name; - char *xmss_filename; /* for state file updates */ - void *xmss_state; /* depends on xmss_name, opaque */ - u_char *xmss_sk; - u_char *xmss_pk; /* KEY_ECDSA_SK and KEY_ED25519_SK */ char *sk_application; uint8_t sk_flags; @@ -236,12 +218,12 @@ int sshkey_match_keyname_to_sigalgs(const char *, const char *); int sshkey_to_certified(struct sshkey *); int sshkey_drop_cert(struct sshkey *); int sshkey_cert_copy(const struct sshkey *, struct sshkey *); -int sshkey_cert_check_authority(const struct sshkey *, int, int, int, +int sshkey_cert_check_authority(const struct sshkey *, int, int, uint64_t, const char *, const char **); -int sshkey_cert_check_authority_now(const struct sshkey *, int, int, int, +int sshkey_cert_check_authority_now(const struct sshkey *, int, int, const char *, const char **); int sshkey_cert_check_host(const struct sshkey *, const char *, - int , const char *, const char **); + const char *, const char **); size_t sshkey_format_cert_validity(const struct sshkey_cert *, char *, size_t) __attribute__((__bounded__(__string__, 2, 3))); int sshkey_check_cert_sigtype(const struct sshkey *, const char *); @@ -277,10 +259,9 @@ int sshkey_to_blob(const struct sshkey *, u_char **, size_t *); int sshkey_to_base64(const struct sshkey *, char **); int sshkey_putb(const struct sshkey *, struct sshbuf *); int sshkey_puts(const struct sshkey *, struct sshbuf *); -int sshkey_puts_opts(const struct sshkey *, struct sshbuf *, - enum sshkey_serialize_rep); int sshkey_plain_to_blob(const struct sshkey *, u_char **, size_t *); int sshkey_putb_plain(const struct sshkey *, struct sshbuf *); +int sshkey_puts_plain(const struct sshkey *, struct sshbuf *); int sshkey_sign(struct sshkey *, u_char **, size_t *, const u_char *, size_t, const char *, const char *, const char *, u_int); @@ -302,8 +283,6 @@ void sshkey_dump_ec_key(const EC_KEY *); /* private key parsing and serialisation */ int sshkey_private_serialize(struct sshkey *key, struct sshbuf *buf); -int sshkey_private_serialize_opt(struct sshkey *key, struct sshbuf *buf, - enum sshkey_serialize_rep); int sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **keyp); /* private key file format parsing and serialisation */ @@ -318,17 +297,18 @@ int sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf *blob, int type, struct sshkey **pubkeyp); int sshkey_check_rsa_length(const struct sshkey *, int); +int ssh_rsa_hash_id_from_keyname(const char *); +const char *ssh_rsa_hash_alg_ident(int); +int ssh_rsa_encode_store_sig(int, const u_char *, size_t, + u_char **, size_t *); +int ssh_ecdsa_encode_store_sig(const struct sshkey *, + const BIGNUM *, const BIGNUM *, u_char **, size_t *); +int ssh_ed25519_encode_store_sig(const u_char *, size_t, + u_char **, size_t *); /* XXX should be internal, but used by ssh-keygen */ int ssh_rsa_complete_crt_parameters(const BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *, BIGNUM **, BIGNUM **); -/* stateful keys (e.g. XMSS) */ -int sshkey_set_filename(struct sshkey *, const char *); -int sshkey_enable_maxsign(struct sshkey *, u_int32_t); -u_int32_t sshkey_signatures_left(const struct sshkey *); -int sshkey_private_serialize_maxsign(struct sshkey *key, - struct sshbuf *buf, u_int32_t maxsign, int); - void sshkey_sig_details_free(struct sshkey_sig_details *); #ifdef WITH_OPENSSL @@ -351,7 +331,6 @@ int check_rsa_length(const RSA *rsa); /* XXX remove */ #if !defined(WITH_OPENSSL) # undef RSA -# undef DSA # undef EC_KEY # undef EC_GROUP # undef EC_POINT diff --git a/sshlogin.c b/sshlogin.c index 06a7b38..f3f4639 100644 --- a/sshlogin.c +++ b/sshlogin.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshlogin.c,v 1.35 2020/10/18 11:32:02 djm Exp $ */ +/* $OpenBSD: sshlogin.c,v 1.37 2026/02/16 23:47:06 jsg Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -48,7 +48,6 @@ #include #include -#include #include #include #include @@ -106,7 +105,7 @@ store_lastlog_message(const char *user, uid_t uid) if (time_string != NULL) { if ((r = sshbuf_put(loginmsg, time_string, strlen(time_string))) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); free(time_string); } # else diff --git a/sshpty.c b/sshpty.c index cae0b97..b3e1e24 100644 --- a/sshpty.c +++ b/sshpty.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshpty.c,v 1.34 2019/07/04 16:20:10 deraadt Exp $ */ +/* $OpenBSD: sshpty.c,v 1.35 2026/02/11 17:05:32 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -17,23 +17,19 @@ #include #include #include -#include #include #include #include -#ifdef HAVE_PATHS_H -# include -#endif +#include #include +#include #include #include #include #include -#ifdef HAVE_UTIL_H -# include -#endif #include +#include #include "sshpty.h" #include "log.h" @@ -173,7 +169,7 @@ pty_setowner(struct passwd *pw, const char *tty) /* Determine the group to make the owner of the tty. */ grp = getgrnam("tty"); if (grp == NULL) - debug("%s: no tty group", __func__); + debug_f("no tty group"); gid = (grp != NULL) ? grp->gr_gid : pw->pw_gid; mode = (grp != NULL) ? 0620 : 0600; diff --git a/sshsig.c b/sshsig.c index 057e1df..5b267d0 100644 --- a/sshsig.c +++ b/sshsig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshsig.c,v 1.35 2024/03/08 22:16:32 djm Exp $ */ +/* $OpenBSD: sshsig.c,v 1.41 2025/12/22 01:49:03 djm Exp $ */ /* * Copyright (c) 2019 Google LLC * @@ -40,9 +40,9 @@ #define MAGIC_PREAMBLE_LEN (sizeof(MAGIC_PREAMBLE) - 1) #define BEGIN_SIGNATURE "-----BEGIN SSH SIGNATURE-----" #define END_SIGNATURE "-----END SSH SIGNATURE-----" -#define RSA_SIGN_ALG "rsa-sha2-512" /* XXX maybe make configurable */ +#define RSA_SIGN_ALG "rsa-sha2-512" #define RSA_SIGN_ALLOWED "rsa-sha2-512,rsa-sha2-256" -#define HASHALG_DEFAULT "sha512" /* XXX maybe make configurable */ +#define HASHALG_DEFAULT "sha512" #define HASHALG_ALLOWED "sha256,sha512" int @@ -190,8 +190,13 @@ sshsig_wrap_sign(struct sshkey *key, const char *hashalg, } /* If using RSA keys then default to a good signature algorithm */ - if (sshkey_type_plain(key->type) == KEY_RSA) + if (sshkey_type_plain(key->type) == KEY_RSA) { sign_alg = RSA_SIGN_ALG; + if (strcmp(hashalg, "sha256") == 0) + sign_alg = "rsa-sha2-256"; + else if (strcmp(hashalg, "sha512") == 0) + sign_alg = "rsa-sha2-512"; + } if (signer != NULL) { if ((r = signer(key, &sig, &slen, @@ -849,8 +854,8 @@ cert_filter_principals(const char *path, u_long linenum, while ((cp = strsep(&principals, ",")) != NULL && *cp != '\0') { /* Check certificate validity */ - if ((r = sshkey_cert_check_authority(cert, 0, 1, 0, - verify_time, NULL, &reason)) != 0) { + if ((r = sshkey_cert_check_authority(cert, 0, 0, verify_time, + NULL, &reason)) != 0) { debug("%s:%lu: principal \"%s\" not authorized: %s", path, linenum, cp, reason); continue; @@ -915,7 +920,7 @@ check_allowed_keys_line(const char *path, u_long linenum, char *line, sshkey_equal_public(sign_key->cert->signature_key, found_key)) { if (principal) { /* Match certificate CA key with specified principal */ - if ((r = sshkey_cert_check_authority(sign_key, 0, 1, 0, + if ((r = sshkey_cert_check_authority(sign_key, 0, 0, verify_time, principal, &reason)) != 0) { error("%s:%lu: certificate not authorized: %s", path, linenum, reason); @@ -1118,11 +1123,12 @@ sshsig_match_principals(const char *path, const char *principal, linesize = 0; } fclose(f); + free(line); if (ret == 0) { if (nprincipals == 0) ret = SSH_ERR_KEY_NOT_FOUND; - if (nprincipalsp != 0) + if (nprincipalsp != NULL) *nprincipalsp = nprincipals; if (principalsp != NULL) { *principalsp = principals; diff --git a/ttymodes.c b/ttymodes.c index 1d20ce8..6102f8d 100644 --- a/ttymodes.c +++ b/ttymodes.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ttymodes.c,v 1.36 2021/01/27 09:26:54 djm Exp $ */ +/* $OpenBSD: ttymodes.c,v 1.37 2026/02/14 00:18:34 jsg Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -56,7 +56,6 @@ #include "log.h" #include "compat.h" #include "sshbuf.h" -#include "ssherr.h" #define TTY_OP_END 0 /* diff --git a/uidswap.c b/uidswap.c index 6ed3024..413b2c6 100644 --- a/uidswap.c +++ b/uidswap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uidswap.c,v 1.42 2019/06/28 13:35:04 deraadt Exp $ */ +/* $OpenBSD: uidswap.c,v 1.43 2026/02/11 17:05:32 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -15,6 +15,7 @@ #include "includes.h" #include +#include #include #include #include @@ -22,8 +23,6 @@ #include #include -#include - #include "log.h" #include "uidswap.h" #include "xmalloc.h" @@ -163,9 +162,9 @@ restore_uid(void) * as well. */ if (setuid(getuid()) == -1) - fatal("%s: setuid failed: %s", __func__, strerror(errno)); + fatal_f("setuid failed: %s", strerror(errno)); if (setgid(getgid()) == -1) - fatal("%s: setgid failed: %s", __func__, strerror(errno)); + fatal_f("setgid failed: %s", strerror(errno)); #endif /* SAVED_IDS_WORK_WITH_SETEUID */ if (setgroups(saved_egroupslen, saved_egroups) == -1) @@ -212,7 +211,7 @@ permanently_set_uid(struct passwd *pw) /* Try restoration of GID if changed (test clearing of saved gid) */ if (old_gid != pw->pw_gid && pw->pw_uid != 0 && (setgid(old_gid) != -1 || setegid(old_gid) != -1)) - fatal("%s: was able to restore old [e]gid", __func__); + fatal_f("was able to restore old [e]gid"); #endif /* Verify GID drop was successful */ @@ -226,7 +225,7 @@ permanently_set_uid(struct passwd *pw) /* Try restoration of UID if changed (test clearing of saved uid) */ if (old_uid != pw->pw_uid && (setuid(old_uid) != -1 || seteuid(old_uid) != -1)) - fatal("%s: was able to restore old [e]uid", __func__); + fatal_f("was able to restore old [e]uid"); #endif /* Verify UID drop was successful */ diff --git a/umac.c b/umac.c index d5958ba..66e6ffe 100644 --- a/umac.c +++ b/umac.c @@ -1,4 +1,4 @@ -/* $OpenBSD: umac.c,v 1.23 2023/03/07 01:30:52 djm Exp $ */ +/* $OpenBSD: umac.c,v 1.30 2026/03/03 09:57:26 dtucker Exp $ */ /* ----------------------------------------------------------------------- * * umac.c -- C Implementation UMAC Message Authentication @@ -6,7 +6,7 @@ * Version 0.93b of rfc4418.txt -- 2006 July 18 * * For a full description of UMAC message authentication see the UMAC - * world-wide-web page at http://www.cs.ucdavis.edu/~rogaway/umac + * world-wide-web page at https://fastcrypto.org/umac/ * Please report bugs and suggestions to the UMAC webpage. * * Copyright (c) 1999-2006 Ted Krovetz @@ -40,7 +40,7 @@ * "Barreto"). The only two files needed are rijndael-alg-fst.c and * rijndael-alg-fst.h. Brian Gladman's version is distributed with the GNU * Public license at http://fp.gladman.plus.com/AES/index.htm. It - * includes a fast IA-32 assembly version. The OpenSSL crypo library is + * includes a fast IA-32 assembly version. The OpenSSL crypto library is * the third. * * 5) With FORCE_C_ONLY flags set to 0, incorrect results are sometimes @@ -53,7 +53,7 @@ /* ---------------------------------------------------------------------- */ #ifndef UMAC_OUTPUT_LEN -#define UMAC_OUTPUT_LEN 8 /* Alowable: 4, 8, 12, 16 */ +#define UMAC_OUTPUT_LEN 8 /* Allowable: 4, 8, 12, 16 */ #endif #if UMAC_OUTPUT_LEN != 4 && UMAC_OUTPUT_LEN != 8 && \ @@ -72,10 +72,12 @@ /* ---------------------------------------------------------------------- */ #include "includes.h" + #include +#include #include #include -#include +#include #include #include @@ -88,10 +90,10 @@ /* ---------------------------------------------------------------------- */ /* The following assumptions may need change on your system */ -typedef u_int8_t UINT8; /* 1 byte */ -typedef u_int16_t UINT16; /* 2 byte */ -typedef u_int32_t UINT32; /* 4 byte */ -typedef u_int64_t UINT64; /* 8 bytes */ +typedef uint8_t UINT8; /* 1 byte */ +typedef uint16_t UINT16; /* 2 byte */ +typedef uint32_t UINT32; /* 4 byte */ +typedef uint64_t UINT64; /* 8 bytes */ typedef unsigned int UWORD; /* Register */ /* ---------------------------------------------------------------------- */ @@ -1089,7 +1091,7 @@ static int uhash_update(uhash_ctx_t ctx, const u_char *input, long len) } /* pass remaining < L1_KEY_LEN bytes of input data to NH */ - if (len) { + if (len > 0 && (unsigned long)len <= UINT32_MAX) { nh_update(&ctx->hash, (const UINT8 *)input, len); ctx->msg_len += len; } diff --git a/version.h b/version.h index 9bd910a..fceafae 100644 --- a/version.h +++ b/version.h @@ -1,6 +1,6 @@ -/* $OpenBSD: version.h,v 1.103 2024/09/19 22:17:44 djm Exp $ */ +/* $OpenBSD: version.h,v 1.108 2026/04/02 07:51:12 djm Exp $ */ -#define SSH_VERSION "OpenSSH_9.9" +#define SSH_VERSION "OpenSSH_10.3" -#define SSH_PORTABLE "p2" +#define SSH_PORTABLE "p1" #define SSH_RELEASE SSH_VERSION SSH_PORTABLE diff --git a/xmalloc.c b/xmalloc.c index 67191e3..a058f08 100644 --- a/xmalloc.c +++ b/xmalloc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xmalloc.c,v 1.37 2022/03/13 23:27:54 cheloha Exp $ */ +/* $OpenBSD: xmalloc.c,v 1.38 2025/05/23 00:40:45 deraadt Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -16,9 +16,7 @@ #include "includes.h" #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include #include @@ -27,7 +25,7 @@ #include "log.h" #if defined(__OpenBSD__) -char *malloc_options = "S"; +const char * const malloc_options = "S"; #endif /* __OpenBSD__ */ void * diff --git a/xmss_commons.c b/xmss_commons.c deleted file mode 100644 index 8d6b80b..0000000 --- a/xmss_commons.c +++ /dev/null @@ -1,36 +0,0 @@ -/* $OpenBSD: xmss_commons.c,v 1.2 2018/02/26 03:56:44 dtucker Exp $ */ -/* -xmss_commons.c 20160722 -Andreas Hülsing -Joost Rijneveld -Public domain. -*/ - -#include "includes.h" -#ifdef WITH_XMSS - -#include "xmss_commons.h" -#include -#include -#ifdef HAVE_STDINT_H -# include -#endif - -void to_byte(unsigned char *out, unsigned long long in, uint32_t bytes) -{ - int32_t i; - for (i = bytes-1; i >= 0; i--) { - out[i] = in & 0xff; - in = in >> 8; - } -} - -#if 0 -void hexdump(const unsigned char *a, size_t len) -{ - size_t i; - for (i = 0; i < len; i++) - printf("%02x", a[i]); -} -#endif -#endif /* WITH_XMSS */ diff --git a/xmss_commons.h b/xmss_commons.h deleted file mode 100644 index a98e479..0000000 --- a/xmss_commons.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifdef WITH_XMSS -/* $OpenBSD: xmss_commons.h,v 1.3 2018/02/26 03:56:44 dtucker Exp $ */ -/* -xmss_commons.h 20160722 -Andreas Hülsing -Joost Rijneveld -Public domain. -*/ -#ifndef XMSS_COMMONS_H -#define XMSS_COMMONS_H - -#include -#ifdef HAVE_STDINT_H -#include -#endif -#endif -void to_byte(unsigned char *output, unsigned long long in, uint32_t bytes); -#if 0 -void hexdump(const unsigned char *a, size_t len); -#endif -#endif /* WITH_XMSS */ diff --git a/xmss_fast.c b/xmss_fast.c deleted file mode 100644 index 421b39a..0000000 --- a/xmss_fast.c +++ /dev/null @@ -1,1106 +0,0 @@ -/* $OpenBSD: xmss_fast.c,v 1.3 2018/03/22 07:06:11 markus Exp $ */ -/* -xmss_fast.c version 20160722 -Andreas Hülsing -Joost Rijneveld -Public domain. -*/ - -#include "includes.h" -#ifdef WITH_XMSS - -#include -#include -#ifdef HAVE_STDINT_H -# include -#endif - -#include "xmss_fast.h" -#include "crypto_api.h" -#include "xmss_wots.h" -#include "xmss_hash.h" - -#include "xmss_commons.h" -#include "xmss_hash_address.h" -// For testing -#include "stdio.h" - - - -/** - * Used for pseudorandom keygeneration, - * generates the seed for the WOTS keypair at address addr - * - * takes n byte sk_seed and returns n byte seed using 32 byte address addr. - */ -static void get_seed(unsigned char *seed, const unsigned char *sk_seed, int n, uint32_t addr[8]) -{ - unsigned char bytes[32]; - // Make sure that chain addr, hash addr, and key bit are 0! - setChainADRS(addr,0); - setHashADRS(addr,0); - setKeyAndMask(addr,0); - // Generate pseudorandom value - addr_to_byte(bytes, addr); - prf(seed, bytes, sk_seed, n); -} - -/** - * Initialize xmss params struct - * parameter names are the same as in the draft - * parameter k is K as used in the BDS algorithm - */ -int xmss_set_params(xmss_params *params, int n, int h, int w, int k) -{ - if (k >= h || k < 2 || (h - k) % 2) { - fprintf(stderr, "For BDS traversal, H - K must be even, with H > K >= 2!\n"); - return 1; - } - params->h = h; - params->n = n; - params->k = k; - wots_params wots_par; - wots_set_params(&wots_par, n, w); - params->wots_par = wots_par; - return 0; -} - -/** - * Initialize BDS state struct - * parameter names are the same as used in the description of the BDS traversal - */ -void xmss_set_bds_state(bds_state *state, unsigned char *stack, int stackoffset, unsigned char *stacklevels, unsigned char *auth, unsigned char *keep, treehash_inst *treehash, unsigned char *retain, int next_leaf) -{ - state->stack = stack; - state->stackoffset = stackoffset; - state->stacklevels = stacklevels; - state->auth = auth; - state->keep = keep; - state->treehash = treehash; - state->retain = retain; - state->next_leaf = next_leaf; -} - -/** - * Initialize xmssmt_params struct - * parameter names are the same as in the draft - * - * Especially h is the total tree height, i.e. the XMSS trees have height h/d - */ -int xmssmt_set_params(xmssmt_params *params, int n, int h, int d, int w, int k) -{ - if (h % d) { - fprintf(stderr, "d must divide h without remainder!\n"); - return 1; - } - params->h = h; - params->d = d; - params->n = n; - params->index_len = (h + 7) / 8; - xmss_params xmss_par; - if (xmss_set_params(&xmss_par, n, (h/d), w, k)) { - return 1; - } - params->xmss_par = xmss_par; - return 0; -} - -/** - * Computes a leaf from a WOTS public key using an L-tree. - */ -static void l_tree(unsigned char *leaf, unsigned char *wots_pk, const xmss_params *params, const unsigned char *pub_seed, uint32_t addr[8]) -{ - unsigned int l = params->wots_par.len; - unsigned int n = params->n; - uint32_t i = 0; - uint32_t height = 0; - uint32_t bound; - - //ADRS.setTreeHeight(0); - setTreeHeight(addr, height); - - while (l > 1) { - bound = l >> 1; //floor(l / 2); - for (i = 0; i < bound; i++) { - //ADRS.setTreeIndex(i); - setTreeIndex(addr, i); - //wots_pk[i] = RAND_HASH(pk[2i], pk[2i + 1], SEED, ADRS); - hash_h(wots_pk+i*n, wots_pk+i*2*n, pub_seed, addr, n); - } - //if ( l % 2 == 1 ) { - if (l & 1) { - //pk[floor(l / 2) + 1] = pk[l]; - memcpy(wots_pk+(l>>1)*n, wots_pk+(l-1)*n, n); - //l = ceil(l / 2); - l=(l>>1)+1; - } - else { - //l = ceil(l / 2); - l=(l>>1); - } - //ADRS.setTreeHeight(ADRS.getTreeHeight() + 1); - height++; - setTreeHeight(addr, height); - } - //return pk[0]; - memcpy(leaf, wots_pk, n); -} - -/** - * Computes the leaf at a given address. First generates the WOTS key pair, then computes leaf using l_tree. As this happens position independent, we only require that addr encodes the right ltree-address. - */ -static void gen_leaf_wots(unsigned char *leaf, const unsigned char *sk_seed, const xmss_params *params, const unsigned char *pub_seed, uint32_t ltree_addr[8], uint32_t ots_addr[8]) -{ - unsigned char seed[params->n]; - unsigned char pk[params->wots_par.keysize]; - - get_seed(seed, sk_seed, params->n, ots_addr); - wots_pkgen(pk, seed, &(params->wots_par), pub_seed, ots_addr); - - l_tree(leaf, pk, params, pub_seed, ltree_addr); -} - -static int treehash_minheight_on_stack(bds_state* state, const xmss_params *params, const treehash_inst *treehash) { - unsigned int r = params->h, i; - for (i = 0; i < treehash->stackusage; i++) { - if (state->stacklevels[state->stackoffset - i - 1] < r) { - r = state->stacklevels[state->stackoffset - i - 1]; - } - } - return r; -} - -/** - * Merkle's TreeHash algorithm. The address only needs to initialize the first 78 bits of addr. Everything else will be set by treehash. - * Currently only used for key generation. - * - */ -static void treehash_setup(unsigned char *node, int height, int index, bds_state *state, const unsigned char *sk_seed, const xmss_params *params, const unsigned char *pub_seed, const uint32_t addr[8]) -{ - unsigned int idx = index; - unsigned int n = params->n; - unsigned int h = params->h; - unsigned int k = params->k; - // use three different addresses because at this point we use all three formats in parallel - uint32_t ots_addr[8]; - uint32_t ltree_addr[8]; - uint32_t node_addr[8]; - // only copy layer and tree address parts - memcpy(ots_addr, addr, 12); - // type = ots - setType(ots_addr, 0); - memcpy(ltree_addr, addr, 12); - setType(ltree_addr, 1); - memcpy(node_addr, addr, 12); - setType(node_addr, 2); - - uint32_t lastnode, i; - unsigned char stack[(height+1)*n]; - unsigned int stacklevels[height+1]; - unsigned int stackoffset=0; - unsigned int nodeh; - - lastnode = idx+(1<treehash[i].h = i; - state->treehash[i].completed = 1; - state->treehash[i].stackusage = 0; - } - - i = 0; - for (; idx < lastnode; idx++) { - setLtreeADRS(ltree_addr, idx); - setOTSADRS(ots_addr, idx); - gen_leaf_wots(stack+stackoffset*n, sk_seed, params, pub_seed, ltree_addr, ots_addr); - stacklevels[stackoffset] = 0; - stackoffset++; - if (h - k > 0 && i == 3) { - memcpy(state->treehash[0].node, stack+stackoffset*n, n); - } - while (stackoffset>1 && stacklevels[stackoffset-1] == stacklevels[stackoffset-2]) - { - nodeh = stacklevels[stackoffset-1]; - if (i >> nodeh == 1) { - memcpy(state->auth + nodeh*n, stack+(stackoffset-1)*n, n); - } - else { - if (nodeh < h - k && i >> nodeh == 3) { - memcpy(state->treehash[nodeh].node, stack+(stackoffset-1)*n, n); - } - else if (nodeh >= h - k) { - memcpy(state->retain + ((1 << (h - 1 - nodeh)) + nodeh - h + (((i >> nodeh) - 3) >> 1)) * n, stack+(stackoffset-1)*n, n); - } - } - setTreeHeight(node_addr, stacklevels[stackoffset-1]); - setTreeIndex(node_addr, (idx >> (stacklevels[stackoffset-1]+1))); - hash_h(stack+(stackoffset-2)*n, stack+(stackoffset-2)*n, pub_seed, - node_addr, n); - stacklevels[stackoffset-2]++; - stackoffset--; - } - i++; - } - - for (i = 0; i < n; i++) - node[i] = stack[i]; -} - -static void treehash_update(treehash_inst *treehash, bds_state *state, const unsigned char *sk_seed, const xmss_params *params, const unsigned char *pub_seed, const uint32_t addr[8]) { - int n = params->n; - - uint32_t ots_addr[8]; - uint32_t ltree_addr[8]; - uint32_t node_addr[8]; - // only copy layer and tree address parts - memcpy(ots_addr, addr, 12); - // type = ots - setType(ots_addr, 0); - memcpy(ltree_addr, addr, 12); - setType(ltree_addr, 1); - memcpy(node_addr, addr, 12); - setType(node_addr, 2); - - setLtreeADRS(ltree_addr, treehash->next_idx); - setOTSADRS(ots_addr, treehash->next_idx); - - unsigned char nodebuffer[2 * n]; - unsigned int nodeheight = 0; - gen_leaf_wots(nodebuffer, sk_seed, params, pub_seed, ltree_addr, ots_addr); - while (treehash->stackusage > 0 && state->stacklevels[state->stackoffset-1] == nodeheight) { - memcpy(nodebuffer + n, nodebuffer, n); - memcpy(nodebuffer, state->stack + (state->stackoffset-1)*n, n); - setTreeHeight(node_addr, nodeheight); - setTreeIndex(node_addr, (treehash->next_idx >> (nodeheight+1))); - hash_h(nodebuffer, nodebuffer, pub_seed, node_addr, n); - nodeheight++; - treehash->stackusage--; - state->stackoffset--; - } - if (nodeheight == treehash->h) { // this also implies stackusage == 0 - memcpy(treehash->node, nodebuffer, n); - treehash->completed = 1; - } - else { - memcpy(state->stack + state->stackoffset*n, nodebuffer, n); - treehash->stackusage++; - state->stacklevels[state->stackoffset] = nodeheight; - state->stackoffset++; - treehash->next_idx++; - } -} - -/** - * Computes a root node given a leaf and an authapth - */ -static void validate_authpath(unsigned char *root, const unsigned char *leaf, unsigned long leafidx, const unsigned char *authpath, const xmss_params *params, const unsigned char *pub_seed, uint32_t addr[8]) -{ - unsigned int n = params->n; - - uint32_t i, j; - unsigned char buffer[2*n]; - - // If leafidx is odd (last bit = 1), current path element is a right child and authpath has to go to the left. - // Otherwise, it is the other way around - if (leafidx & 1) { - for (j = 0; j < n; j++) - buffer[n+j] = leaf[j]; - for (j = 0; j < n; j++) - buffer[j] = authpath[j]; - } - else { - for (j = 0; j < n; j++) - buffer[j] = leaf[j]; - for (j = 0; j < n; j++) - buffer[n+j] = authpath[j]; - } - authpath += n; - - for (i=0; i < params->h-1; i++) { - setTreeHeight(addr, i); - leafidx >>= 1; - setTreeIndex(addr, leafidx); - if (leafidx&1) { - hash_h(buffer+n, buffer, pub_seed, addr, n); - for (j = 0; j < n; j++) - buffer[j] = authpath[j]; - } - else { - hash_h(buffer, buffer, pub_seed, addr, n); - for (j = 0; j < n; j++) - buffer[j+n] = authpath[j]; - } - authpath += n; - } - setTreeHeight(addr, (params->h-1)); - leafidx >>= 1; - setTreeIndex(addr, leafidx); - hash_h(root, buffer, pub_seed, addr, n); -} - -/** - * Performs one treehash update on the instance that needs it the most. - * Returns 1 if such an instance was not found - **/ -static char bds_treehash_update(bds_state *state, unsigned int updates, const unsigned char *sk_seed, const xmss_params *params, unsigned char *pub_seed, const uint32_t addr[8]) { - uint32_t i, j; - unsigned int level, l_min, low; - unsigned int h = params->h; - unsigned int k = params->k; - unsigned int used = 0; - - for (j = 0; j < updates; j++) { - l_min = h; - level = h - k; - for (i = 0; i < h - k; i++) { - if (state->treehash[i].completed) { - low = h; - } - else if (state->treehash[i].stackusage == 0) { - low = i; - } - else { - low = treehash_minheight_on_stack(state, params, &(state->treehash[i])); - } - if (low < l_min) { - level = i; - l_min = low; - } - } - if (level == h - k) { - break; - } - treehash_update(&(state->treehash[level]), state, sk_seed, params, pub_seed, addr); - used++; - } - return updates - used; -} - -/** - * Updates the state (typically NEXT_i) by adding a leaf and updating the stack - * Returns 1 if all leaf nodes have already been processed - **/ -static char bds_state_update(bds_state *state, const unsigned char *sk_seed, const xmss_params *params, unsigned char *pub_seed, const uint32_t addr[8]) { - uint32_t ltree_addr[8]; - uint32_t node_addr[8]; - uint32_t ots_addr[8]; - - int n = params->n; - int h = params->h; - int k = params->k; - - int nodeh; - int idx = state->next_leaf; - if (idx == 1 << h) { - return 1; - } - - // only copy layer and tree address parts - memcpy(ots_addr, addr, 12); - // type = ots - setType(ots_addr, 0); - memcpy(ltree_addr, addr, 12); - setType(ltree_addr, 1); - memcpy(node_addr, addr, 12); - setType(node_addr, 2); - - setOTSADRS(ots_addr, idx); - setLtreeADRS(ltree_addr, idx); - - gen_leaf_wots(state->stack+state->stackoffset*n, sk_seed, params, pub_seed, ltree_addr, ots_addr); - - state->stacklevels[state->stackoffset] = 0; - state->stackoffset++; - if (h - k > 0 && idx == 3) { - memcpy(state->treehash[0].node, state->stack+state->stackoffset*n, n); - } - while (state->stackoffset>1 && state->stacklevels[state->stackoffset-1] == state->stacklevels[state->stackoffset-2]) { - nodeh = state->stacklevels[state->stackoffset-1]; - if (idx >> nodeh == 1) { - memcpy(state->auth + nodeh*n, state->stack+(state->stackoffset-1)*n, n); - } - else { - if (nodeh < h - k && idx >> nodeh == 3) { - memcpy(state->treehash[nodeh].node, state->stack+(state->stackoffset-1)*n, n); - } - else if (nodeh >= h - k) { - memcpy(state->retain + ((1 << (h - 1 - nodeh)) + nodeh - h + (((idx >> nodeh) - 3) >> 1)) * n, state->stack+(state->stackoffset-1)*n, n); - } - } - setTreeHeight(node_addr, state->stacklevels[state->stackoffset-1]); - setTreeIndex(node_addr, (idx >> (state->stacklevels[state->stackoffset-1]+1))); - hash_h(state->stack+(state->stackoffset-2)*n, state->stack+(state->stackoffset-2)*n, pub_seed, node_addr, n); - - state->stacklevels[state->stackoffset-2]++; - state->stackoffset--; - } - state->next_leaf++; - return 0; -} - -/** - * Returns the auth path for node leaf_idx and computes the auth path for the - * next leaf node, using the algorithm described by Buchmann, Dahmen and Szydlo - * in "Post Quantum Cryptography", Springer 2009. - */ -static void bds_round(bds_state *state, const unsigned long leaf_idx, const unsigned char *sk_seed, const xmss_params *params, unsigned char *pub_seed, uint32_t addr[8]) -{ - unsigned int i; - unsigned int n = params->n; - unsigned int h = params->h; - unsigned int k = params->k; - - unsigned int tau = h; - unsigned int startidx; - unsigned int offset, rowidx; - unsigned char buf[2 * n]; - - uint32_t ots_addr[8]; - uint32_t ltree_addr[8]; - uint32_t node_addr[8]; - // only copy layer and tree address parts - memcpy(ots_addr, addr, 12); - // type = ots - setType(ots_addr, 0); - memcpy(ltree_addr, addr, 12); - setType(ltree_addr, 1); - memcpy(node_addr, addr, 12); - setType(node_addr, 2); - - for (i = 0; i < h; i++) { - if (! ((leaf_idx >> i) & 1)) { - tau = i; - break; - } - } - - if (tau > 0) { - memcpy(buf, state->auth + (tau-1) * n, n); - // we need to do this before refreshing state->keep to prevent overwriting - memcpy(buf + n, state->keep + ((tau-1) >> 1) * n, n); - } - if (!((leaf_idx >> (tau + 1)) & 1) && (tau < h - 1)) { - memcpy(state->keep + (tau >> 1)*n, state->auth + tau*n, n); - } - if (tau == 0) { - setLtreeADRS(ltree_addr, leaf_idx); - setOTSADRS(ots_addr, leaf_idx); - gen_leaf_wots(state->auth, sk_seed, params, pub_seed, ltree_addr, ots_addr); - } - else { - setTreeHeight(node_addr, (tau-1)); - setTreeIndex(node_addr, leaf_idx >> tau); - hash_h(state->auth + tau * n, buf, pub_seed, node_addr, n); - for (i = 0; i < tau; i++) { - if (i < h - k) { - memcpy(state->auth + i * n, state->treehash[i].node, n); - } - else { - offset = (1 << (h - 1 - i)) + i - h; - rowidx = ((leaf_idx >> i) - 1) >> 1; - memcpy(state->auth + i * n, state->retain + (offset + rowidx) * n, n); - } - } - - for (i = 0; i < ((tau < h - k) ? tau : (h - k)); i++) { - startidx = leaf_idx + 1 + 3 * (1 << i); - if (startidx < 1U << h) { - state->treehash[i].h = i; - state->treehash[i].next_idx = startidx; - state->treehash[i].completed = 0; - state->treehash[i].stackusage = 0; - } - } - } -} - -/* - * Generates a XMSS key pair for a given parameter set. - * Format sk: [(32bit) idx || SK_SEED || SK_PRF || PUB_SEED || root] - * Format pk: [root || PUB_SEED] omitting algo oid. - */ -int xmss_keypair(unsigned char *pk, unsigned char *sk, bds_state *state, xmss_params *params) -{ - unsigned int n = params->n; - // Set idx = 0 - sk[0] = 0; - sk[1] = 0; - sk[2] = 0; - sk[3] = 0; - // Init SK_SEED (n byte), SK_PRF (n byte), and PUB_SEED (n byte) - randombytes(sk+4, 3*n); - // Copy PUB_SEED to public key - memcpy(pk+n, sk+4+2*n, n); - - uint32_t addr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - - // Compute root - treehash_setup(pk, params->h, 0, state, sk+4, params, sk+4+2*n, addr); - // copy root to sk - memcpy(sk+4+3*n, pk, n); - return 0; -} - -/** - * Signs a message. - * Returns - * 1. an array containing the signature followed by the message AND - * 2. an updated secret key! - * - */ -int xmss_sign(unsigned char *sk, bds_state *state, unsigned char *sig_msg, unsigned long long *sig_msg_len, const unsigned char *msg, unsigned long long msglen, const xmss_params *params) -{ - unsigned int h = params->h; - unsigned int n = params->n; - unsigned int k = params->k; - uint16_t i = 0; - - // Extract SK - unsigned long idx = ((unsigned long)sk[0] << 24) | ((unsigned long)sk[1] << 16) | ((unsigned long)sk[2] << 8) | sk[3]; - unsigned char sk_seed[n]; - memcpy(sk_seed, sk+4, n); - unsigned char sk_prf[n]; - memcpy(sk_prf, sk+4+n, n); - unsigned char pub_seed[n]; - memcpy(pub_seed, sk+4+2*n, n); - - // index as 32 bytes string - unsigned char idx_bytes_32[32]; - to_byte(idx_bytes_32, idx, 32); - - unsigned char hash_key[3*n]; - - // Update SK - sk[0] = ((idx + 1) >> 24) & 255; - sk[1] = ((idx + 1) >> 16) & 255; - sk[2] = ((idx + 1) >> 8) & 255; - sk[3] = (idx + 1) & 255; - // -- Secret key for this non-forward-secure version is now updated. - // -- A productive implementation should use a file handle instead and write the updated secret key at this point! - - // Init working params - unsigned char R[n]; - unsigned char msg_h[n]; - unsigned char ots_seed[n]; - uint32_t ots_addr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - - // --------------------------------- - // Message Hashing - // --------------------------------- - - // Message Hash: - // First compute pseudorandom value - prf(R, idx_bytes_32, sk_prf, n); - // Generate hash key (R || root || idx) - memcpy(hash_key, R, n); - memcpy(hash_key+n, sk+4+3*n, n); - to_byte(hash_key+2*n, idx, n); - // Then use it for message digest - h_msg(msg_h, msg, msglen, hash_key, 3*n, n); - - // Start collecting signature - *sig_msg_len = 0; - - // Copy index to signature - sig_msg[0] = (idx >> 24) & 255; - sig_msg[1] = (idx >> 16) & 255; - sig_msg[2] = (idx >> 8) & 255; - sig_msg[3] = idx & 255; - - sig_msg += 4; - *sig_msg_len += 4; - - // Copy R to signature - for (i = 0; i < n; i++) - sig_msg[i] = R[i]; - - sig_msg += n; - *sig_msg_len += n; - - // ---------------------------------- - // Now we start to "really sign" - // ---------------------------------- - - // Prepare Address - setType(ots_addr, 0); - setOTSADRS(ots_addr, idx); - - // Compute seed for OTS key pair - get_seed(ots_seed, sk_seed, n, ots_addr); - - // Compute WOTS signature - wots_sign(sig_msg, msg_h, ots_seed, &(params->wots_par), pub_seed, ots_addr); - - sig_msg += params->wots_par.keysize; - *sig_msg_len += params->wots_par.keysize; - - // the auth path was already computed during the previous round - memcpy(sig_msg, state->auth, h*n); - - if (idx < (1U << h) - 1) { - bds_round(state, idx, sk_seed, params, pub_seed, ots_addr); - bds_treehash_update(state, (h - k) >> 1, sk_seed, params, pub_seed, ots_addr); - } - -/* TODO: save key/bds state here! */ - - sig_msg += params->h*n; - *sig_msg_len += params->h*n; - - //Whipe secret elements? - //zerobytes(tsk, CRYPTO_SECRETKEYBYTES); - - - memcpy(sig_msg, msg, msglen); - *sig_msg_len += msglen; - - return 0; -} - -/** - * Verifies a given message signature pair under a given public key. - */ -int xmss_sign_open(unsigned char *msg, unsigned long long *msglen, const unsigned char *sig_msg, unsigned long long sig_msg_len, const unsigned char *pk, const xmss_params *params) -{ - unsigned int n = params->n; - - unsigned long long i, m_len; - unsigned long idx=0; - unsigned char wots_pk[params->wots_par.keysize]; - unsigned char pkhash[n]; - unsigned char root[n]; - unsigned char msg_h[n]; - unsigned char hash_key[3*n]; - - unsigned char pub_seed[n]; - memcpy(pub_seed, pk+n, n); - - // Init addresses - uint32_t ots_addr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - uint32_t ltree_addr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - uint32_t node_addr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - - setType(ots_addr, 0); - setType(ltree_addr, 1); - setType(node_addr, 2); - - // Extract index - idx = ((unsigned long)sig_msg[0] << 24) | ((unsigned long)sig_msg[1] << 16) | ((unsigned long)sig_msg[2] << 8) | sig_msg[3]; - printf("verify:: idx = %lu\n", idx); - - // Generate hash key (R || root || idx) - memcpy(hash_key, sig_msg+4,n); - memcpy(hash_key+n, pk, n); - to_byte(hash_key+2*n, idx, n); - - sig_msg += (n+4); - sig_msg_len -= (n+4); - - // hash message - unsigned long long tmp_sig_len = params->wots_par.keysize+params->h*n; - m_len = sig_msg_len - tmp_sig_len; - h_msg(msg_h, sig_msg + tmp_sig_len, m_len, hash_key, 3*n, n); - - //----------------------- - // Verify signature - //----------------------- - - // Prepare Address - setOTSADRS(ots_addr, idx); - // Check WOTS signature - wots_pkFromSig(wots_pk, sig_msg, msg_h, &(params->wots_par), pub_seed, ots_addr); - - sig_msg += params->wots_par.keysize; - sig_msg_len -= params->wots_par.keysize; - - // Compute Ltree - setLtreeADRS(ltree_addr, idx); - l_tree(pkhash, wots_pk, params, pub_seed, ltree_addr); - - // Compute root - validate_authpath(root, pkhash, idx, sig_msg, params, pub_seed, node_addr); - - sig_msg += params->h*n; - sig_msg_len -= params->h*n; - - for (i = 0; i < n; i++) - if (root[i] != pk[i]) - goto fail; - - *msglen = sig_msg_len; - for (i = 0; i < *msglen; i++) - msg[i] = sig_msg[i]; - - return 0; - - -fail: - *msglen = sig_msg_len; - for (i = 0; i < *msglen; i++) - msg[i] = 0; - *msglen = -1; - return -1; -} - -/* - * Generates a XMSSMT key pair for a given parameter set. - * Format sk: [(ceil(h/8) bit) idx || SK_SEED || SK_PRF || PUB_SEED || root] - * Format pk: [root || PUB_SEED] omitting algo oid. - */ -int xmssmt_keypair(unsigned char *pk, unsigned char *sk, bds_state *states, unsigned char *wots_sigs, xmssmt_params *params) -{ - unsigned int n = params->n; - unsigned int i; - unsigned char ots_seed[params->n]; - // Set idx = 0 - for (i = 0; i < params->index_len; i++) { - sk[i] = 0; - } - // Init SK_SEED (n byte), SK_PRF (n byte), and PUB_SEED (n byte) - randombytes(sk+params->index_len, 3*n); - // Copy PUB_SEED to public key - memcpy(pk+n, sk+params->index_len+2*n, n); - - // Set address to point on the single tree on layer d-1 - uint32_t addr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - setLayerADRS(addr, (params->d-1)); - // Set up state and compute wots signatures for all but topmost tree root - for (i = 0; i < params->d - 1; i++) { - // Compute seed for OTS key pair - treehash_setup(pk, params->xmss_par.h, 0, states + i, sk+params->index_len, &(params->xmss_par), pk+n, addr); - setLayerADRS(addr, (i+1)); - get_seed(ots_seed, sk+params->index_len, n, addr); - wots_sign(wots_sigs + i*params->xmss_par.wots_par.keysize, pk, ots_seed, &(params->xmss_par.wots_par), pk+n, addr); - } - treehash_setup(pk, params->xmss_par.h, 0, states + i, sk+params->index_len, &(params->xmss_par), pk+n, addr); - memcpy(sk+params->index_len+3*n, pk, n); - return 0; -} - -/** - * Signs a message. - * Returns - * 1. an array containing the signature followed by the message AND - * 2. an updated secret key! - * - */ -int xmssmt_sign(unsigned char *sk, bds_state *states, unsigned char *wots_sigs, unsigned char *sig_msg, unsigned long long *sig_msg_len, const unsigned char *msg, unsigned long long msglen, const xmssmt_params *params) -{ - unsigned int n = params->n; - - unsigned int tree_h = params->xmss_par.h; - unsigned int h = params->h; - unsigned int k = params->xmss_par.k; - unsigned int idx_len = params->index_len; - uint64_t idx_tree; - uint32_t idx_leaf; - uint64_t i, j; - int needswap_upto = -1; - unsigned int updates; - - unsigned char sk_seed[n]; - unsigned char sk_prf[n]; - unsigned char pub_seed[n]; - // Init working params - unsigned char R[n]; - unsigned char msg_h[n]; - unsigned char hash_key[3*n]; - unsigned char ots_seed[n]; - uint32_t addr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - uint32_t ots_addr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - unsigned char idx_bytes_32[32]; - bds_state tmp; - - // Extract SK - unsigned long long idx = 0; - for (i = 0; i < idx_len; i++) { - idx |= ((unsigned long long)sk[i]) << 8*(idx_len - 1 - i); - } - - memcpy(sk_seed, sk+idx_len, n); - memcpy(sk_prf, sk+idx_len+n, n); - memcpy(pub_seed, sk+idx_len+2*n, n); - - // Update SK - for (i = 0; i < idx_len; i++) { - sk[i] = ((idx + 1) >> 8*(idx_len - 1 - i)) & 255; - } - // -- Secret key for this non-forward-secure version is now updated. - // -- A productive implementation should use a file handle instead and write the updated secret key at this point! - - - // --------------------------------- - // Message Hashing - // --------------------------------- - - // Message Hash: - // First compute pseudorandom value - to_byte(idx_bytes_32, idx, 32); - prf(R, idx_bytes_32, sk_prf, n); - // Generate hash key (R || root || idx) - memcpy(hash_key, R, n); - memcpy(hash_key+n, sk+idx_len+3*n, n); - to_byte(hash_key+2*n, idx, n); - - // Then use it for message digest - h_msg(msg_h, msg, msglen, hash_key, 3*n, n); - - // Start collecting signature - *sig_msg_len = 0; - - // Copy index to signature - for (i = 0; i < idx_len; i++) { - sig_msg[i] = (idx >> 8*(idx_len - 1 - i)) & 255; - } - - sig_msg += idx_len; - *sig_msg_len += idx_len; - - // Copy R to signature - for (i = 0; i < n; i++) - sig_msg[i] = R[i]; - - sig_msg += n; - *sig_msg_len += n; - - // ---------------------------------- - // Now we start to "really sign" - // ---------------------------------- - - // Handle lowest layer separately as it is slightly different... - - // Prepare Address - setType(ots_addr, 0); - idx_tree = idx >> tree_h; - idx_leaf = (idx & ((1 << tree_h)-1)); - setLayerADRS(ots_addr, 0); - setTreeADRS(ots_addr, idx_tree); - setOTSADRS(ots_addr, idx_leaf); - - // Compute seed for OTS key pair - get_seed(ots_seed, sk_seed, n, ots_addr); - - // Compute WOTS signature - wots_sign(sig_msg, msg_h, ots_seed, &(params->xmss_par.wots_par), pub_seed, ots_addr); - - sig_msg += params->xmss_par.wots_par.keysize; - *sig_msg_len += params->xmss_par.wots_par.keysize; - - memcpy(sig_msg, states[0].auth, tree_h*n); - sig_msg += tree_h*n; - *sig_msg_len += tree_h*n; - - // prepare signature of remaining layers - for (i = 1; i < params->d; i++) { - // put WOTS signature in place - memcpy(sig_msg, wots_sigs + (i-1)*params->xmss_par.wots_par.keysize, params->xmss_par.wots_par.keysize); - - sig_msg += params->xmss_par.wots_par.keysize; - *sig_msg_len += params->xmss_par.wots_par.keysize; - - // put AUTH nodes in place - memcpy(sig_msg, states[i].auth, tree_h*n); - sig_msg += tree_h*n; - *sig_msg_len += tree_h*n; - } - - updates = (tree_h - k) >> 1; - - setTreeADRS(addr, (idx_tree + 1)); - // mandatory update for NEXT_0 (does not count towards h-k/2) if NEXT_0 exists - if ((1 + idx_tree) * (1 << tree_h) + idx_leaf < (1ULL << h)) { - bds_state_update(&states[params->d], sk_seed, &(params->xmss_par), pub_seed, addr); - } - - for (i = 0; i < params->d; i++) { - // check if we're not at the end of a tree - if (! (((idx + 1) & ((1ULL << ((i+1)*tree_h)) - 1)) == 0)) { - idx_leaf = (idx >> (tree_h * i)) & ((1 << tree_h)-1); - idx_tree = (idx >> (tree_h * (i+1))); - setLayerADRS(addr, i); - setTreeADRS(addr, idx_tree); - if (i == (unsigned int) (needswap_upto + 1)) { - bds_round(&states[i], idx_leaf, sk_seed, &(params->xmss_par), pub_seed, addr); - } - updates = bds_treehash_update(&states[i], updates, sk_seed, &(params->xmss_par), pub_seed, addr); - setTreeADRS(addr, (idx_tree + 1)); - // if a NEXT-tree exists for this level; - if ((1 + idx_tree) * (1 << tree_h) + idx_leaf < (1ULL << (h - tree_h * i))) { - if (i > 0 && updates > 0 && states[params->d + i].next_leaf < (1ULL << h)) { - bds_state_update(&states[params->d + i], sk_seed, &(params->xmss_par), pub_seed, addr); - updates--; - } - } - } - else if (idx < (1ULL << h) - 1) { - memcpy(&tmp, states+params->d + i, sizeof(bds_state)); - memcpy(states+params->d + i, states + i, sizeof(bds_state)); - memcpy(states + i, &tmp, sizeof(bds_state)); - - setLayerADRS(ots_addr, (i+1)); - setTreeADRS(ots_addr, ((idx + 1) >> ((i+2) * tree_h))); - setOTSADRS(ots_addr, (((idx >> ((i+1) * tree_h)) + 1) & ((1 << tree_h)-1))); - - get_seed(ots_seed, sk+params->index_len, n, ots_addr); - wots_sign(wots_sigs + i*params->xmss_par.wots_par.keysize, states[i].stack, ots_seed, &(params->xmss_par.wots_par), pub_seed, ots_addr); - - states[params->d + i].stackoffset = 0; - states[params->d + i].next_leaf = 0; - - updates--; // WOTS-signing counts as one update - needswap_upto = i; - for (j = 0; j < tree_h-k; j++) { - states[i].treehash[j].completed = 1; - } - } - } - - //Whipe secret elements? - //zerobytes(tsk, CRYPTO_SECRETKEYBYTES); - - memcpy(sig_msg, msg, msglen); - *sig_msg_len += msglen; - - return 0; -} - -/** - * Verifies a given message signature pair under a given public key. - */ -int xmssmt_sign_open(unsigned char *msg, unsigned long long *msglen, const unsigned char *sig_msg, unsigned long long sig_msg_len, const unsigned char *pk, const xmssmt_params *params) -{ - unsigned int n = params->n; - - unsigned int tree_h = params->xmss_par.h; - unsigned int idx_len = params->index_len; - uint64_t idx_tree; - uint32_t idx_leaf; - - unsigned long long i, m_len; - unsigned long long idx=0; - unsigned char wots_pk[params->xmss_par.wots_par.keysize]; - unsigned char pkhash[n]; - unsigned char root[n]; - unsigned char msg_h[n]; - unsigned char hash_key[3*n]; - - unsigned char pub_seed[n]; - memcpy(pub_seed, pk+n, n); - - // Init addresses - uint32_t ots_addr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - uint32_t ltree_addr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - uint32_t node_addr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - - // Extract index - for (i = 0; i < idx_len; i++) { - idx |= ((unsigned long long)sig_msg[i]) << (8*(idx_len - 1 - i)); - } - printf("verify:: idx = %llu\n", idx); - sig_msg += idx_len; - sig_msg_len -= idx_len; - - // Generate hash key (R || root || idx) - memcpy(hash_key, sig_msg,n); - memcpy(hash_key+n, pk, n); - to_byte(hash_key+2*n, idx, n); - - sig_msg += n; - sig_msg_len -= n; - - - // hash message (recall, R is now on pole position at sig_msg - unsigned long long tmp_sig_len = (params->d * params->xmss_par.wots_par.keysize) + (params->h * n); - m_len = sig_msg_len - tmp_sig_len; - h_msg(msg_h, sig_msg + tmp_sig_len, m_len, hash_key, 3*n, n); - - - //----------------------- - // Verify signature - //----------------------- - - // Prepare Address - idx_tree = idx >> tree_h; - idx_leaf = (idx & ((1 << tree_h)-1)); - setLayerADRS(ots_addr, 0); - setTreeADRS(ots_addr, idx_tree); - setType(ots_addr, 0); - - memcpy(ltree_addr, ots_addr, 12); - setType(ltree_addr, 1); - - memcpy(node_addr, ltree_addr, 12); - setType(node_addr, 2); - - setOTSADRS(ots_addr, idx_leaf); - - // Check WOTS signature - wots_pkFromSig(wots_pk, sig_msg, msg_h, &(params->xmss_par.wots_par), pub_seed, ots_addr); - - sig_msg += params->xmss_par.wots_par.keysize; - sig_msg_len -= params->xmss_par.wots_par.keysize; - - // Compute Ltree - setLtreeADRS(ltree_addr, idx_leaf); - l_tree(pkhash, wots_pk, &(params->xmss_par), pub_seed, ltree_addr); - - // Compute root - validate_authpath(root, pkhash, idx_leaf, sig_msg, &(params->xmss_par), pub_seed, node_addr); - - sig_msg += tree_h*n; - sig_msg_len -= tree_h*n; - - for (i = 1; i < params->d; i++) { - // Prepare Address - idx_leaf = (idx_tree & ((1 << tree_h)-1)); - idx_tree = idx_tree >> tree_h; - - setLayerADRS(ots_addr, i); - setTreeADRS(ots_addr, idx_tree); - setType(ots_addr, 0); - - memcpy(ltree_addr, ots_addr, 12); - setType(ltree_addr, 1); - - memcpy(node_addr, ltree_addr, 12); - setType(node_addr, 2); - - setOTSADRS(ots_addr, idx_leaf); - - // Check WOTS signature - wots_pkFromSig(wots_pk, sig_msg, root, &(params->xmss_par.wots_par), pub_seed, ots_addr); - - sig_msg += params->xmss_par.wots_par.keysize; - sig_msg_len -= params->xmss_par.wots_par.keysize; - - // Compute Ltree - setLtreeADRS(ltree_addr, idx_leaf); - l_tree(pkhash, wots_pk, &(params->xmss_par), pub_seed, ltree_addr); - - // Compute root - validate_authpath(root, pkhash, idx_leaf, sig_msg, &(params->xmss_par), pub_seed, node_addr); - - sig_msg += tree_h*n; - sig_msg_len -= tree_h*n; - - } - - for (i = 0; i < n; i++) - if (root[i] != pk[i]) - goto fail; - - *msglen = sig_msg_len; - for (i = 0; i < *msglen; i++) - msg[i] = sig_msg[i]; - - return 0; - - -fail: - *msglen = sig_msg_len; - for (i = 0; i < *msglen; i++) - msg[i] = 0; - *msglen = -1; - return -1; -} -#endif /* WITH_XMSS */ diff --git a/xmss_fast.h b/xmss_fast.h deleted file mode 100644 index 2ffba70..0000000 --- a/xmss_fast.h +++ /dev/null @@ -1,111 +0,0 @@ -#ifdef WITH_XMSS -/* $OpenBSD: xmss_fast.h,v 1.2 2018/02/26 03:56:44 dtucker Exp $ */ -/* -xmss_fast.h version 20160722 -Andreas Hülsing -Joost Rijneveld -Public domain. -*/ - -#include "xmss_wots.h" - -#ifndef XMSS_H -#define XMSS_H -typedef struct{ - unsigned int level; - unsigned long long subtree; - unsigned int subleaf; -} leafaddr; - -typedef struct{ - wots_params wots_par; - unsigned int n; - unsigned int h; - unsigned int k; -} xmss_params; - -typedef struct{ - xmss_params xmss_par; - unsigned int n; - unsigned int h; - unsigned int d; - unsigned int index_len; -} xmssmt_params; - -typedef struct{ - unsigned int h; - unsigned int next_idx; - unsigned int stackusage; - unsigned char completed; - unsigned char *node; -} treehash_inst; - -typedef struct { - unsigned char *stack; - unsigned int stackoffset; - unsigned char *stacklevels; - unsigned char *auth; - unsigned char *keep; - treehash_inst *treehash; - unsigned char *retain; - unsigned int next_leaf; -} bds_state; - -/** - * Initialize BDS state struct - * parameter names are the same as used in the description of the BDS traversal - */ -void xmss_set_bds_state(bds_state *state, unsigned char *stack, int stackoffset, unsigned char *stacklevels, unsigned char *auth, unsigned char *keep, treehash_inst *treehash, unsigned char *retain, int next_leaf); -/** - * Initializes parameter set. - * Needed, for any of the other methods. - */ -int xmss_set_params(xmss_params *params, int n, int h, int w, int k); -/** - * Initialize xmssmt_params struct - * parameter names are the same as in the draft - * - * Especially h is the total tree height, i.e. the XMSS trees have height h/d - */ -int xmssmt_set_params(xmssmt_params *params, int n, int h, int d, int w, int k); -/** - * Generates a XMSS key pair for a given parameter set. - * Format sk: [(32bit) idx || SK_SEED || SK_PRF || PUB_SEED || root] - * Format pk: [root || PUB_SEED] omitting algo oid. - */ -int xmss_keypair(unsigned char *pk, unsigned char *sk, bds_state *state, xmss_params *params); -/** - * Signs a message. - * Returns - * 1. an array containing the signature followed by the message AND - * 2. an updated secret key! - * - */ -int xmss_sign(unsigned char *sk, bds_state *state, unsigned char *sig_msg, unsigned long long *sig_msg_len, const unsigned char *msg,unsigned long long msglen, const xmss_params *params); -/** - * Verifies a given message signature pair under a given public key. - * - * Note: msg and msglen are pure outputs which carry the message in case verification succeeds. The (input) message is assumed to be within sig_msg which has the form (sig||msg). - */ -int xmss_sign_open(unsigned char *msg,unsigned long long *msglen, const unsigned char *sig_msg,unsigned long long sig_msg_len, const unsigned char *pk, const xmss_params *params); - -/* - * Generates a XMSSMT key pair for a given parameter set. - * Format sk: [(ceil(h/8) bit) idx || SK_SEED || SK_PRF || PUB_SEED || root] - * Format pk: [root || PUB_SEED] omitting algo oid. - */ -int xmssmt_keypair(unsigned char *pk, unsigned char *sk, bds_state *states, unsigned char *wots_sigs, xmssmt_params *params); -/** - * Signs a message. - * Returns - * 1. an array containing the signature followed by the message AND - * 2. an updated secret key! - * - */ -int xmssmt_sign(unsigned char *sk, bds_state *state, unsigned char *wots_sigs, unsigned char *sig_msg, unsigned long long *sig_msg_len, const unsigned char *msg, unsigned long long msglen, const xmssmt_params *params); -/** - * Verifies a given message signature pair under a given public key. - */ -int xmssmt_sign_open(unsigned char *msg, unsigned long long *msglen, const unsigned char *sig_msg, unsigned long long sig_msg_len, const unsigned char *pk, const xmssmt_params *params); -#endif -#endif /* WITH_XMSS */ diff --git a/xmss_hash.c b/xmss_hash.c deleted file mode 100644 index 70c126a..0000000 --- a/xmss_hash.c +++ /dev/null @@ -1,137 +0,0 @@ -/* $OpenBSD: xmss_hash.c,v 1.4 2023/12/20 00:06:25 jsg Exp $ */ -/* -hash.c version 20160722 -Andreas Hülsing -Joost Rijneveld -Public domain. -*/ - -#include "includes.h" -#ifdef WITH_XMSS - -#include "xmss_hash_address.h" -#include "xmss_commons.h" -#include "xmss_hash.h" - -#include -#ifdef HAVE_STDINT_H -# include -#endif -#include -#include - -int core_hash_SHA2(unsigned char *, const unsigned int, const unsigned char *, - unsigned int, const unsigned char *, unsigned long long, unsigned int); - -unsigned char* addr_to_byte(unsigned char *bytes, const uint32_t addr[8]){ -#if IS_LITTLE_ENDIAN==1 - int i = 0; - for(i=0;i<8;i++) - to_byte(bytes+i*4, addr[i],4); - return bytes; -#else - memcpy(bytes, addr, 32); - return bytes; -#endif -} - -int core_hash_SHA2(unsigned char *out, const unsigned int type, const unsigned char *key, unsigned int keylen, const unsigned char *in, unsigned long long inlen, unsigned int n){ - unsigned long long i = 0; - unsigned char buf[inlen + n + keylen]; - - // Input is (toByte(X, 32) || KEY || M) - - // set toByte - to_byte(buf, type, n); - - for (i=0; i < keylen; i++) { - buf[i+n] = key[i]; - } - - for (i=0; i < inlen; i++) { - buf[keylen + n + i] = in[i]; - } - - if (n == 32) { - SHA256(buf, inlen + keylen + n, out); - return 0; - } - else { - if (n == 64) { - SHA512(buf, inlen + keylen + n, out); - return 0; - } - } - return 1; -} - -/** - * Implements PRF - */ -int prf(unsigned char *out, const unsigned char *in, const unsigned char *key, unsigned int keylen) -{ - return core_hash_SHA2(out, 3, key, keylen, in, 32, keylen); -} - -/* - * Implements H_msg - */ -int h_msg(unsigned char *out, const unsigned char *in, unsigned long long inlen, const unsigned char *key, const unsigned int keylen, const unsigned int n) -{ - if (keylen != 3*n){ - // H_msg takes 3n-bit keys, but n does not match the keylength of keylen - return -1; - } - return core_hash_SHA2(out, 2, key, keylen, in, inlen, n); -} - -/** - * We assume the left half is in in[0]...in[n-1] - */ -int hash_h(unsigned char *out, const unsigned char *in, const unsigned char *pub_seed, uint32_t addr[8], const unsigned int n) -{ - - unsigned char buf[2*n]; - unsigned char key[n]; - unsigned char bitmask[2*n]; - unsigned char byte_addr[32]; - unsigned int i; - - setKeyAndMask(addr, 0); - addr_to_byte(byte_addr, addr); - prf(key, byte_addr, pub_seed, n); - // Use MSB order - setKeyAndMask(addr, 1); - addr_to_byte(byte_addr, addr); - prf(bitmask, byte_addr, pub_seed, n); - setKeyAndMask(addr, 2); - addr_to_byte(byte_addr, addr); - prf(bitmask+n, byte_addr, pub_seed, n); - for (i = 0; i < 2*n; i++) { - buf[i] = in[i] ^ bitmask[i]; - } - return core_hash_SHA2(out, 1, key, n, buf, 2*n, n); -} - -int hash_f(unsigned char *out, const unsigned char *in, const unsigned char *pub_seed, uint32_t addr[8], const unsigned int n) -{ - unsigned char buf[n]; - unsigned char key[n]; - unsigned char bitmask[n]; - unsigned char byte_addr[32]; - unsigned int i; - - setKeyAndMask(addr, 0); - addr_to_byte(byte_addr, addr); - prf(key, byte_addr, pub_seed, n); - - setKeyAndMask(addr, 1); - addr_to_byte(byte_addr, addr); - prf(bitmask, byte_addr, pub_seed, n); - - for (i = 0; i < n; i++) { - buf[i] = in[i] ^ bitmask[i]; - } - return core_hash_SHA2(out, 0, key, n, buf, n, n); -} -#endif /* WITH_XMSS */ diff --git a/xmss_hash.h b/xmss_hash.h deleted file mode 100644 index d19c621..0000000 --- a/xmss_hash.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifdef WITH_XMSS -/* $OpenBSD: xmss_hash.h,v 1.2 2018/02/26 03:56:44 dtucker Exp $ */ -/* -hash.h version 20160722 -Andreas Hülsing -Joost Rijneveld -Public domain. -*/ - -#ifndef HASH_H -#define HASH_H - -#define IS_LITTLE_ENDIAN 1 - -unsigned char* addr_to_byte(unsigned char *bytes, const uint32_t addr[8]); -int prf(unsigned char *out, const unsigned char *in, const unsigned char *key, unsigned int keylen); -int h_msg(unsigned char *out,const unsigned char *in,unsigned long long inlen, const unsigned char *key, const unsigned int keylen, const unsigned int n); -int hash_h(unsigned char *out, const unsigned char *in, const unsigned char *pub_seed, uint32_t addr[8], const unsigned int n); -int hash_f(unsigned char *out, const unsigned char *in, const unsigned char *pub_seed, uint32_t addr[8], const unsigned int n); - -#endif -#endif /* WITH_XMSS */ diff --git a/xmss_hash_address.c b/xmss_hash_address.c deleted file mode 100644 index 2702c45..0000000 --- a/xmss_hash_address.c +++ /dev/null @@ -1,66 +0,0 @@ -/* $OpenBSD: xmss_hash_address.c,v 1.2 2018/02/26 03:56:44 dtucker Exp $ */ -/* -hash_address.c version 20160722 -Andreas Hülsing -Joost Rijneveld -Public domain. -*/ -#include "includes.h" -#ifdef WITH_XMSS - -#ifdef HAVE_STDINT_H -# include -#endif -#include "xmss_hash_address.h" /* prototypes */ - -void setLayerADRS(uint32_t adrs[8], uint32_t layer){ - adrs[0] = layer; -} - -void setTreeADRS(uint32_t adrs[8], uint64_t tree){ - adrs[1] = (uint32_t) (tree >> 32); - adrs[2] = (uint32_t) tree; -} - -void setType(uint32_t adrs[8], uint32_t type){ - adrs[3] = type; - int i; - for(i = 4; i < 8; i++){ - adrs[i] = 0; - } -} - -void setKeyAndMask(uint32_t adrs[8], uint32_t keyAndMask){ - adrs[7] = keyAndMask; -} - -// OTS - -void setOTSADRS(uint32_t adrs[8], uint32_t ots){ - adrs[4] = ots; -} - -void setChainADRS(uint32_t adrs[8], uint32_t chain){ - adrs[5] = chain; -} - -void setHashADRS(uint32_t adrs[8], uint32_t hash){ - adrs[6] = hash; -} - -// L-tree - -void setLtreeADRS(uint32_t adrs[8], uint32_t ltree){ - adrs[4] = ltree; -} - -// Hash Tree & L-tree - -void setTreeHeight(uint32_t adrs[8], uint32_t treeHeight){ - adrs[5] = treeHeight; -} - -void setTreeIndex(uint32_t adrs[8], uint32_t treeIndex){ - adrs[6] = treeIndex; -} -#endif /* WITH_XMSS */ diff --git a/xmss_hash_address.h b/xmss_hash_address.h deleted file mode 100644 index 66bb4cc..0000000 --- a/xmss_hash_address.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifdef WITH_XMSS -/* $OpenBSD: xmss_hash_address.h,v 1.2 2018/02/26 03:56:44 dtucker Exp $ */ -/* -hash_address.h version 20160722 -Andreas Hülsing -Joost Rijneveld -Public domain. -*/ - -#ifdef HAVE_STDINT_H -#include -#endif - -void setLayerADRS(uint32_t adrs[8], uint32_t layer); - -void setTreeADRS(uint32_t adrs[8], uint64_t tree); - -void setType(uint32_t adrs[8], uint32_t type); - -void setKeyAndMask(uint32_t adrs[8], uint32_t keyAndMask); - -// OTS - -void setOTSADRS(uint32_t adrs[8], uint32_t ots); - -void setChainADRS(uint32_t adrs[8], uint32_t chain); - -void setHashADRS(uint32_t adrs[8], uint32_t hash); - -// L-tree - -void setLtreeADRS(uint32_t adrs[8], uint32_t ltree); - -// Hash Tree & L-tree - -void setTreeHeight(uint32_t adrs[8], uint32_t treeHeight); - -void setTreeIndex(uint32_t adrs[8], uint32_t treeIndex); - -#endif /* WITH_XMSS */ diff --git a/xmss_wots.c b/xmss_wots.c deleted file mode 100644 index 993e661..0000000 --- a/xmss_wots.c +++ /dev/null @@ -1,192 +0,0 @@ -/* $OpenBSD: xmss_wots.c,v 1.3 2018/04/10 00:10:49 djm Exp $ */ -/* -wots.c version 20160722 -Andreas Hülsing -Joost Rijneveld -Public domain. -*/ - -#include "includes.h" -#ifdef WITH_XMSS - -#include -#ifdef HAVE_STDINT_H -# include -#endif -#include -#include "xmss_commons.h" -#include "xmss_hash.h" -#include "xmss_wots.h" -#include "xmss_hash_address.h" - - -/* libm-free version of log2() for wots */ -static inline int -wots_log2(uint32_t v) -{ - int b; - - for (b = sizeof (v) * CHAR_BIT - 1; b >= 0; b--) { - if ((1U << b) & v) { - return b; - } - } - return 0; -} - -void -wots_set_params(wots_params *params, int n, int w) -{ - params->n = n; - params->w = w; - params->log_w = wots_log2(params->w); - params->len_1 = (CHAR_BIT * n) / params->log_w; - params->len_2 = (wots_log2(params->len_1 * (w - 1)) / params->log_w) + 1; - params->len = params->len_1 + params->len_2; - params->keysize = params->len * params->n; -} - -/** - * Helper method for pseudorandom key generation - * Expands an n-byte array into a len*n byte array - * this is done using PRF - */ -static void expand_seed(unsigned char *outseeds, const unsigned char *inseed, const wots_params *params) -{ - uint32_t i = 0; - unsigned char ctr[32]; - for(i = 0; i < params->len; i++){ - to_byte(ctr, i, 32); - prf((outseeds + (i*params->n)), ctr, inseed, params->n); - } -} - -/** - * Computes the chaining function. - * out and in have to be n-byte arrays - * - * interprets in as start-th value of the chain - * addr has to contain the address of the chain - */ -static void gen_chain(unsigned char *out, const unsigned char *in, unsigned int start, unsigned int steps, const wots_params *params, const unsigned char *pub_seed, uint32_t addr[8]) -{ - uint32_t i, j; - for (j = 0; j < params->n; j++) - out[j] = in[j]; - - for (i = start; i < (start+steps) && i < params->w; i++) { - setHashADRS(addr, i); - hash_f(out, out, pub_seed, addr, params->n); - } -} - -/** - * base_w algorithm as described in draft. - * - * - */ -static void base_w(int *output, const int out_len, const unsigned char *input, const wots_params *params) -{ - int in = 0; - int out = 0; - uint32_t total = 0; - int bits = 0; - int consumed = 0; - - for (consumed = 0; consumed < out_len; consumed++) { - if (bits == 0) { - total = input[in]; - in++; - bits += 8; - } - bits -= params->log_w; - output[out] = (total >> bits) & (params->w - 1); - out++; - } -} - -void wots_pkgen(unsigned char *pk, const unsigned char *sk, const wots_params *params, const unsigned char *pub_seed, uint32_t addr[8]) -{ - uint32_t i; - expand_seed(pk, sk, params); - for (i=0; i < params->len; i++) { - setChainADRS(addr, i); - gen_chain(pk+i*params->n, pk+i*params->n, 0, params->w-1, params, pub_seed, addr); - } -} - - -int wots_sign(unsigned char *sig, const unsigned char *msg, const unsigned char *sk, const wots_params *params, const unsigned char *pub_seed, uint32_t addr[8]) -{ - //int basew[params->len]; - int csum = 0; - uint32_t i = 0; - int *basew = calloc(params->len, sizeof(int)); - if (basew == NULL) - return -1; - - base_w(basew, params->len_1, msg, params); - - for (i=0; i < params->len_1; i++) { - csum += params->w - 1 - basew[i]; - } - - csum = csum << (8 - ((params->len_2 * params->log_w) % 8)); - - int len_2_bytes = ((params->len_2 * params->log_w) + 7) / 8; - - unsigned char csum_bytes[len_2_bytes]; - to_byte(csum_bytes, csum, len_2_bytes); - - int csum_basew[params->len_2]; - base_w(csum_basew, params->len_2, csum_bytes, params); - - for (i = 0; i < params->len_2; i++) { - basew[params->len_1 + i] = csum_basew[i]; - } - - expand_seed(sig, sk, params); - - for (i = 0; i < params->len; i++) { - setChainADRS(addr, i); - gen_chain(sig+i*params->n, sig+i*params->n, 0, basew[i], params, pub_seed, addr); - } - free(basew); - return 0; -} - -int wots_pkFromSig(unsigned char *pk, const unsigned char *sig, const unsigned char *msg, const wots_params *params, const unsigned char *pub_seed, uint32_t addr[8]) -{ - int csum = 0; - uint32_t i = 0; - int *basew = calloc(params->len, sizeof(int)); - if (basew == NULL) - return -1; - - base_w(basew, params->len_1, msg, params); - - for (i=0; i < params->len_1; i++) { - csum += params->w - 1 - basew[i]; - } - - csum = csum << (8 - ((params->len_2 * params->log_w) % 8)); - - int len_2_bytes = ((params->len_2 * params->log_w) + 7) / 8; - - unsigned char csum_bytes[len_2_bytes]; - to_byte(csum_bytes, csum, len_2_bytes); - - int csum_basew[params->len_2]; - base_w(csum_basew, params->len_2, csum_bytes, params); - - for (i = 0; i < params->len_2; i++) { - basew[params->len_1 + i] = csum_basew[i]; - } - for (i=0; i < params->len; i++) { - setChainADRS(addr, i); - gen_chain(pk+i*params->n, sig+i*params->n, basew[i], params->w-1-basew[i], params, pub_seed, addr); - } - free(basew); - return 0; -} -#endif /* WITH_XMSS */ diff --git a/xmss_wots.h b/xmss_wots.h deleted file mode 100644 index 1eebf3b..0000000 --- a/xmss_wots.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifdef WITH_XMSS -/* $OpenBSD: xmss_wots.h,v 1.3 2018/02/26 12:14:53 dtucker Exp $ */ -/* -wots.h version 20160722 -Andreas Hülsing -Joost Rijneveld -Public domain. -*/ - -#ifndef WOTS_H -#define WOTS_H - -#ifdef HAVE_STDINT_H -#include "stdint.h" -#endif - -/** - * WOTS parameter set - * - * Meaning as defined in draft-irtf-cfrg-xmss-hash-based-signatures-02 - */ -typedef struct { - uint32_t len_1; - uint32_t len_2; - uint32_t len; - uint32_t n; - uint32_t w; - uint32_t log_w; - uint32_t keysize; -} wots_params; - -/** - * Set the WOTS parameters, - * only m, n, w are required as inputs, - * len, len_1, and len_2 are computed from those. - * - * Assumes w is a power of 2 - */ -void wots_set_params(wots_params *params, int n, int w); - -/** - * WOTS key generation. Takes a 32byte seed for the secret key, expands it to a full WOTS secret key and computes the corresponding public key. - * For this it takes the seed pub_seed which is used to generate bitmasks and hash keys and the address of this WOTS key pair addr - * - * params, must have been initialized before using wots_set params for params ! This is not done in this function - * - * Places the computed public key at address pk. - */ -void wots_pkgen(unsigned char *pk, const unsigned char *sk, const wots_params *params, const unsigned char *pub_seed, uint32_t addr[8]); - -/** - * Takes a m-byte message and the 32-byte seed for the secret key to compute a signature that is placed at "sig". - * - */ -int wots_sign(unsigned char *sig, const unsigned char *msg, const unsigned char *sk, const wots_params *params, const unsigned char *pub_seed, uint32_t addr[8]); - -/** - * Takes a WOTS signature, a m-byte message and computes a WOTS public key that it places at pk. - * - */ -int wots_pkFromSig(unsigned char *pk, const unsigned char *sig, const unsigned char *msg, const wots_params *params, const unsigned char *pub_seed, uint32_t addr[8]); - -#endif -#endif /* WITH_XMSS */