head 1.64; access; symbols netbsd-10-0-RC6:1.64 netbsd-10-0-RC5:1.64 netbsd-10-0-RC4:1.64 netbsd-10-0-RC3:1.64 netbsd-10-0-RC2:1.64 thorpej-ifq:1.64.0.8 thorpej-ifq-base:1.64 thorpej-altq-separation:1.64.0.6 thorpej-altq-separation-base:1.64 netbsd-10-0-RC1:1.64 netbsd-10:1.64.0.4 netbsd-10-base:1.64 bouyer-sunxi-drm:1.64.0.2 bouyer-sunxi-drm-base:1.64 netbsd-9-3-RELEASE:1.53 thorpej-i2c-spi-conf2:1.61.0.12 thorpej-i2c-spi-conf2-base:1.61 thorpej-futex2:1.61.0.10 thorpej-futex2-base:1.61 thorpej-cfargs2:1.61.0.8 thorpej-cfargs2-base:1.61 cjep_sun2x-base1:1.61 cjep_sun2x:1.61.0.6 cjep_sun2x-base:1.61 cjep_staticlib_x-base1:1.61 netbsd-9-2-RELEASE:1.53 cjep_staticlib_x:1.61.0.4 cjep_staticlib_x-base:1.61 thorpej-i2c-spi-conf:1.61.0.2 thorpej-i2c-spi-conf-base:1.61 thorpej-cfargs:1.57.0.4 thorpej-cfargs-base:1.61 thorpej-futex:1.57.0.2 thorpej-futex-base:1.57 netbsd-9-1-RELEASE:1.53 bouyer-xenpvh-base2:1.54 phil-wifi-20200421:1.54 bouyer-xenpvh-base1:1.54 phil-wifi-20200411:1.54 bouyer-xenpvh:1.54.0.6 bouyer-xenpvh-base:1.54 is-mlppp:1.54.0.4 is-mlppp-base:1.54 phil-wifi-20200406:1.54 netbsd-8-2-RELEASE:1.51.2.1 ad-namecache-base3:1.54 netbsd-9-0-RELEASE:1.53 netbsd-9-0-RC2:1.53 ad-namecache-base2:1.54 ad-namecache-base1:1.54 ad-namecache:1.54.0.2 ad-namecache-base:1.54 netbsd-9-0-RC1:1.53 phil-wifi-20191119:1.54 netbsd-9:1.53.0.2 netbsd-9-base:1.53 phil-wifi-20190609:1.52 netbsd-8-1-RELEASE:1.51.2.1 netbsd-8-1-RC1:1.51.2.1 isaki-audio2:1.52.0.8 isaki-audio2-base:1.52 pgoyette-compat-merge-20190127:1.52 pgoyette-compat-20190127:1.52 pgoyette-compat-20190118:1.52 pgoyette-compat-1226:1.52 pgoyette-compat-1126:1.52 pgoyette-compat-1020:1.52 pgoyette-compat-0930:1.52 pgoyette-compat-0906:1.52 netbsd-7-2-RELEASE:1.46 pgoyette-compat-0728:1.52 netbsd-8-0-RELEASE:1.51.2.1 phil-wifi:1.52.0.6 phil-wifi-base:1.52 pgoyette-compat-0625:1.52 netbsd-8-0-RC2:1.51.2.1 pgoyette-compat-0521:1.52 pgoyette-compat-0502:1.52 pgoyette-compat-0422:1.52 netbsd-8-0-RC1:1.51.2.1 pgoyette-compat-0415:1.52 pgoyette-compat-0407:1.52 pgoyette-compat-0330:1.52 pgoyette-compat-0322:1.52 pgoyette-compat-0315:1.52 netbsd-7-1-2-RELEASE:1.46 pgoyette-compat:1.52.0.4 pgoyette-compat-base:1.52 netbsd-7-1-1-RELEASE:1.46 tls-maxphys-base-20171202:1.52 matt-nb8-mediatek:1.51.2.1.0.2 matt-nb8-mediatek-base:1.51.2.1 nick-nhusb-base-20170825:1.52 perseant-stdc-iso10646:1.52.0.2 perseant-stdc-iso10646-base:1.52 netbsd-8:1.51.0.2 netbsd-8-base:1.51 prg-localcount2-base3:1.50 prg-localcount2-base2:1.49 prg-localcount2-base1:1.49 prg-localcount2:1.49.0.2 prg-localcount2-base:1.49 pgoyette-localcount-20170426:1.49 bouyer-socketcan-base1:1.49 jdolecek-ncq:1.47.0.6 jdolecek-ncq-base:1.47 pgoyette-localcount-20170320:1.47 netbsd-7-1:1.46.0.10 netbsd-7-1-RELEASE:1.46 netbsd-7-1-RC2:1.46 nick-nhusb-base-20170204:1.47 netbsd-7-nhusb-base-20170116:1.46 bouyer-socketcan:1.47.0.4 bouyer-socketcan-base:1.47 pgoyette-localcount-20170107:1.47 netbsd-7-1-RC1:1.46 nick-nhusb-base-20161204:1.47 pgoyette-localcount-20161104:1.47 netbsd-7-0-2-RELEASE:1.46 nick-nhusb-base-20161004:1.47 localcount-20160914:1.47 netbsd-7-nhusb:1.46.0.8 netbsd-7-nhusb-base:1.46 pgoyette-localcount-20160806:1.47 pgoyette-localcount-20160726:1.47 pgoyette-localcount:1.47.0.2 pgoyette-localcount-base:1.47 nick-nhusb-base-20160907:1.47 nick-nhusb-base-20160529:1.47 netbsd-7-0-1-RELEASE:1.46 nick-nhusb-base-20160422:1.47 nick-nhusb-base-20160319:1.47 nick-nhusb-base-20151226:1.47 netbsd-7-0:1.46.0.6 netbsd-7-0-RELEASE:1.46 nick-nhusb-base-20150921:1.47 netbsd-7-0-RC3:1.46 netbsd-7-0-RC2:1.46 netbsd-7-0-RC1:1.46 nick-nhusb-base-20150606:1.46 nick-nhusb-base-20150406:1.46 nick-nhusb:1.46.0.4 nick-nhusb-base:1.46 netbsd-5-2-3-RELEASE:1.20.20.1 netbsd-5-1-5-RELEASE:1.20.20.1 netbsd-6-0-6-RELEASE:1.39 netbsd-6-1-5-RELEASE:1.39 netbsd-7:1.46.0.2 netbsd-7-base:1.46 yamt-pagecache-base9:1.44 yamt-pagecache-tag8:1.38.2.2 netbsd-6-1-4-RELEASE:1.39 netbsd-6-0-5-RELEASE:1.39 tls-earlyentropy:1.44.0.2 tls-earlyentropy-base:1.46 riastradh-xf86-video-intel-2-7-1-pre-2-21-15:1.44 riastradh-drm2-base3:1.44 netbsd-6-1-3-RELEASE:1.39 netbsd-6-0-4-RELEASE:1.39 netbsd-5-2-2-RELEASE:1.20.20.1 netbsd-5-1-4-RELEASE:1.20.20.1 netbsd-6-1-2-RELEASE:1.39 netbsd-6-0-3-RELEASE:1.39 netbsd-5-2-1-RELEASE:1.20.20.1 netbsd-5-1-3-RELEASE:1.20.20.1 rmind-smpnet-nbase:1.44 netbsd-6-1-1-RELEASE:1.39 riastradh-drm2-base2:1.42 riastradh-drm2-base1:1.42 riastradh-drm2:1.42.0.4 riastradh-drm2-base:1.42 rmind-smpnet:1.42.0.2 rmind-smpnet-base:1.44 netbsd-6-1:1.39.0.10 netbsd-6-0-2-RELEASE:1.39 netbsd-6-1-RELEASE:1.39 khorben-n900:1.41.0.6 netbsd-6-1-RC4:1.39 netbsd-6-1-RC3:1.39 agc-symver:1.41.0.4 agc-symver-base:1.41 netbsd-6-1-RC2:1.39 netbsd-6-1-RC1:1.39 yamt-pagecache-base8:1.40 netbsd-5-2:1.20.20.1.0.6 netbsd-6-0-1-RELEASE:1.39 yamt-pagecache-base7:1.40 netbsd-5-2-RELEASE:1.20.20.1 netbsd-5-2-RC1:1.20.20.1 matt-nb6-plus-nbase:1.39 yamt-pagecache-base6:1.40 netbsd-6-0:1.39.0.8 netbsd-6-0-RELEASE:1.39 netbsd-6-0-RC2:1.39 tls-maxphys:1.40.0.2 tls-maxphys-base:1.46 matt-nb6-plus:1.39.0.6 matt-nb6-plus-base:1.39 netbsd-6-0-RC1:1.39 jmcneill-usbmp-base10:1.39 yamt-pagecache-base5:1.39 jmcneill-usbmp-base9:1.39 yamt-pagecache-base4:1.39 jmcneill-usbmp-base8:1.39 jmcneill-usbmp-base7:1.39 jmcneill-usbmp-base6:1.39 jmcneill-usbmp-base5:1.39 jmcneill-usbmp-base4:1.39 jmcneill-usbmp-base3:1.39 jmcneill-usbmp-pre-base2:1.39 jmcneill-usbmp-base2:1.39 netbsd-6:1.39.0.4 netbsd-6-base:1.39 netbsd-5-1-2-RELEASE:1.20.20.1 netbsd-5-1-1-RELEASE:1.20.20.1 jmcneill-usbmp:1.39.0.2 jmcneill-usbmp-base:1.39 jmcneill-audiomp3:1.38.0.4 jmcneill-audiomp3-base:1.38 yamt-pagecache-base3:1.38 yamt-pagecache-base2:1.38 yamt-pagecache:1.38.0.2 yamt-pagecache-base:1.38 rmind-uvmplock-nbase:1.38 cherry-xenmp:1.37.0.2 cherry-xenmp-base:1.37 bouyer-quota2-nbase:1.29 bouyer-quota2:1.26.0.4 bouyer-quota2-base:1.27 jruoho-x86intr:1.26.0.2 jruoho-x86intr-base:1.26 matt-mips64-premerge-20101231:1.26 matt-nb5-mips64-premerge-20101231:1.20 matt-nb5-pq3:1.20.20.1.0.4 matt-nb5-pq3-base:1.20.20.1 netbsd-5-1:1.20.20.1.0.2 netbsd-5-1-RELEASE:1.20.20.1 uebayasi-xip-base4:1.26 uebayasi-xip-base3:1.26 yamt-nfs-mp-base11:1.26 netbsd-5-1-RC4:1.20.20.1 matt-nb5-mips64-k15:1.20 uebayasi-xip-base2:1.26 yamt-nfs-mp-base10:1.26 netbsd-5-1-RC3:1.20.20.1 netbsd-5-1-RC2:1.20.20.1 uebayasi-xip-base1:1.25 netbsd-5-1-RC1:1.20.20.1 rmind-uvmplock:1.25.0.4 rmind-uvmplock-base:1.38 yamt-nfs-mp-base9:1.25 uebayasi-xip:1.25.0.2 uebayasi-xip-base:1.25 netbsd-5-0-2-RELEASE:1.20 matt-nb5-mips64-premerge-20091211:1.20 matt-premerge-20091211:1.25 yamt-nfs-mp-base8:1.25 matt-nb5-mips64-u2-k2-k4-k7-k8-k9:1.20 matt-nb4-mips64-k7-u2a-k9b:1.20 matt-nb5-mips64-u1-k1-k5:1.20 yamt-nfs-mp-base7:1.25 matt-nb5-mips64:1.20.0.26 netbsd-5-0-1-RELEASE:1.20 jymxensuspend-base:1.25 yamt-nfs-mp-base6:1.25 yamt-nfs-mp-base5:1.25 yamt-nfs-mp-base4:1.25 jym-xensuspend-nbase:1.25 yamt-nfs-mp-base3:1.25 nick-hppapmap-base4:1.25 nick-hppapmap-base3:1.25 netbsd-5-0:1.20.0.24 netbsd-5-0-RELEASE:1.20 netbsd-5-0-RC4:1.20 netbsd-5-0-RC3:1.20 nick-hppapmap-base2:1.21 netbsd-5-0-RC2:1.20 jym-xensuspend:1.21.0.2 jym-xensuspend-base:1.25 netbsd-5-0-RC1:1.20 haad-dm-base2:1.20 haad-nbase2:1.20 ad-audiomp2:1.20.0.22 ad-audiomp2-base:1.20 netbsd-5:1.20.0.20 netbsd-5-base:1.20 nick-hppapmap:1.20.0.18 nick-hppapmap-base:1.25 matt-mips64-base2:1.20 matt-mips64:1.17.0.32 haad-dm-base1:1.20 wrstuden-revivesa-base-4:1.20 netbsd-4-0-1-RELEASE:1.15 wrstuden-revivesa-base-3:1.20 wrstuden-revivesa-base-2:1.20 wrstuden-fixsa-newbase:1.15 nick-csl-alignment-base5:1.17 haad-dm:1.20.0.16 haad-dm-base:1.20 wrstuden-revivesa-base-1:1.20 simonb-wapbl-nbase:1.20 yamt-pf42-base4:1.20 simonb-wapbl:1.20.0.14 simonb-wapbl-base:1.20 yamt-pf42-base3:1.20 hpcarm-cleanup-nbase:1.20 yamt-pf42-baseX:1.20 yamt-pf42-base2:1.20 yamt-nfs-mp-base2:1.20 wrstuden-revivesa:1.20.0.12 wrstuden-revivesa-base:1.20 yamt-nfs-mp:1.20.0.10 yamt-nfs-mp-base:1.20 yamt-pf42:1.20.0.8 yamt-pf42-base:1.20 ad-socklock-base1:1.20 yamt-lazymbuf-base15:1.20 yamt-lazymbuf-base14:1.20 keiichi-mipv6-nbase:1.20 mjf-devfs2:1.20.0.6 mjf-devfs2-base:1.21 nick-net80211-sync:1.20.0.4 nick-net80211-sync-base:1.20 keiichi-mipv6:1.20.0.2 keiichi-mipv6-base:1.20 bouyer-xeni386-merge1:1.17 matt-armv6-prevmlocking:1.17 wrstuden-fixsa-base-1:1.15 vmlocking2-base3:1.17 netbsd-4-0:1.15.0.8 netbsd-4-0-RELEASE:1.15 bouyer-xeni386-nbase:1.17 yamt-kmem-base3:1.17 cube-autoconf:1.17.0.30 cube-autoconf-base:1.17 yamt-kmem-base2:1.17 bouyer-xeni386:1.17.0.28 bouyer-xeni386-base:1.17 yamt-kmem:1.17.0.26 yamt-kmem-base:1.17 vmlocking2-base2:1.17 reinoud-bufcleanup-nbase:1.17 vmlocking2:1.17.0.24 vmlocking2-base1:1.17 netbsd-4-0-RC5:1.15 matt-nb4-arm:1.15.0.6 matt-nb4-arm-base:1.15 matt-armv6-nbase:1.20 jmcneill-base:1.17 netbsd-4-0-RC4:1.15 mjf-devfs:1.17.0.22 mjf-devfs-base:1.20 bouyer-xenamd64-base2:1.17 vmlocking-nbase:1.17 yamt-x86pmap-base4:1.17 bouyer-xenamd64:1.17.0.20 bouyer-xenamd64-base:1.17 netbsd-4-0-RC3:1.15 yamt-x86pmap-base3:1.17 yamt-x86pmap-base2:1.17 netbsd-4-0-RC2:1.15 yamt-x86pmap:1.17.0.18 yamt-x86pmap-base:1.17 netbsd-4-0-RC1:1.15 matt-armv6:1.17.0.16 matt-armv6-base:1.17 matt-mips64-base:1.17 jmcneill-pm:1.17.0.14 jmcneill-pm-base:1.17 hpcarm-cleanup:1.17.0.12 hpcarm-cleanup-base:1.20 nick-csl-alignment:1.17.0.10 nick-csl-alignment-base:1.17 netbsd-3-1-1-RELEASE:1.9 netbsd-3-0-3-RELEASE:1.9 yamt-idlelwp-base8:1.17 wrstuden-fixsa:1.15.0.4 wrstuden-fixsa-base:1.15 thorpej-atomic:1.17.0.8 thorpej-atomic-base:1.17 reinoud-bufcleanup:1.17.0.6 reinoud-bufcleanup-base:1.17 mjf-ufs-trans:1.17.0.4 mjf-ufs-trans-base:1.17 vmlocking:1.17.0.2 vmlocking-base:1.17 ad-audiomp:1.16.0.4 ad-audiomp-base:1.16 yamt-idlelwp:1.16.0.2 post-newlock2-merge:1.15 newlock2-nbase:1.15 yamt-splraiseipl-base5:1.15 yamt-splraiseipl-base4:1.15 yamt-splraiseipl-base3:1.15 abandoned-netbsd-4-base:1.13 abandoned-netbsd-4:1.13.0.6 netbsd-3-1:1.9.0.14 netbsd-3-1-RELEASE:1.9 netbsd-3-0-2-RELEASE:1.9 yamt-splraiseipl-base2:1.14 netbsd-3-1-RC4:1.9 yamt-splraiseipl:1.13.0.10 yamt-splraiseipl-base:1.13 netbsd-3-1-RC3:1.9 yamt-pdpolicy-base9:1.13 newlock2:1.13.0.8 newlock2-base:1.15 yamt-pdpolicy-base8:1.13 netbsd-3-1-RC2:1.9 netbsd-3-1-RC1:1.9 yamt-pdpolicy-base7:1.13 netbsd-4:1.15.0.2 netbsd-4-base:1.15 yamt-pdpolicy-base6:1.13 chap-midi-nbase:1.13 netbsd-3-0-1-RELEASE:1.9 gdamore-uart:1.13.0.4 gdamore-uart-base:1.13 simonb-timcounters-final:1.11.6.1 yamt-pdpolicy-base5:1.13 chap-midi:1.13.0.2 chap-midi-base:1.13 yamt-pdpolicy-base4:1.13 yamt-pdpolicy-base3:1.12 peter-altq-base:1.11 peter-altq:1.11.0.12 yamt-pdpolicy-base2:1.11 elad-kernelauth-base:1.13 elad-kernelauth:1.11.0.10 yamt-pdpolicy:1.11.0.8 yamt-pdpolicy-base:1.11 yamt-uio_vmspace-base5:1.11 simonb-timecounters:1.11.0.6 simonb-timecounters-base:1.13 rpaulo-netinet-merge-pcb:1.11.0.4 rpaulo-netinet-merge-pcb-base:1.13 yamt-uio_vmspace:1.11.0.2 netbsd-3-0:1.9.0.12 netbsd-3-0-RELEASE:1.9 netbsd-3-0-RC6:1.9 yamt-readahead-base3:1.11 netbsd-3-0-RC5:1.9 netbsd-3-0-RC4:1.9 netbsd-3-0-RC3:1.9 yamt-readahead-base2:1.9 netbsd-3-0-RC2:1.9 yamt-readahead-pervnode:1.9 yamt-readahead-perfile:1.9 yamt-readahead:1.9.0.10 yamt-readahead-base:1.9 netbsd-3-0-RC1:1.9 yamt-vop-base3:1.9 netbsd-2-0-3-RELEASE:1.8 netbsd-2-1:1.8.0.16 yamt-vop-base2:1.9 thorpej-vnode-attr:1.9.0.8 thorpej-vnode-attr-base:1.9 netbsd-2-1-RELEASE:1.8 yamt-vop:1.9.0.6 yamt-vop-base:1.9 netbsd-2-1-RC6:1.8 netbsd-2-1-RC5:1.8 netbsd-2-1-RC4:1.8 netbsd-2-1-RC3:1.8 netbsd-2-1-RC2:1.8 netbsd-2-1-RC1:1.8 yamt-lazymbuf:1.9.0.4 yamt-km-base4:1.9 netbsd-2-0-2-RELEASE:1.8 yamt-km-base3:1.9 netbsd-3:1.9.0.2 netbsd-3-base:1.9 yamt-km-base2:1.8 yamt-km:1.8.0.12 yamt-km-base:1.8 kent-audio2:1.8.0.10 kent-audio2-base:1.9 netbsd-2-0-1-RELEASE:1.8 kent-audio1-beforemerge:1.8 netbsd-2:1.8.0.8 netbsd-2-base:1.8 kent-audio1:1.8.0.6 kent-audio1-base:1.8 netbsd-2-0-RELEASE:1.8 netbsd-2-0-RC5:1.8 netbsd-2-0-RC4:1.8 netbsd-2-0-RC3:1.8 netbsd-2-0-RC2:1.8 netbsd-2-0-RC1:1.8 ktrace-lwp-base:1.11 ktrace-lwp:1.8.0.4 netbsd-2-0:1.8.0.2 netbsd-2-0-base:1.8; locks; strict; comment @ * @; 1.64 date 2022.05.22.11.39.27; author riastradh; state Exp; branches; next 1.63; commitid iQWditfyvh6NP2FD; 1.63 date 2022.05.22.11.38.59; author riastradh; state Exp; branches; next 1.62; commitid 6Yv8IgmLkuTDP2FD; 1.62 date 2022.05.22.11.29.25; author riastradh; state Exp; branches; next 1.61; commitid 2FuFW4selzvmM2FD; 1.61 date 2021.04.06.03.38.04; author knakahara; state Exp; branches; next 1.60; commitid IX60Bkq6qWvGnbOC; 1.60 date 2021.04.05.01.24.50; author knakahara; state Exp; branches; next 1.59; commitid D5FWCq8LxGZYF2OC; 1.59 date 2021.04.05.01.23.15; author knakahara; state Exp; branches; next 1.58; commitid WDiU39v0CJBsF2OC; 1.58 date 2021.04.05.01.22.22; author knakahara; state Exp; branches; next 1.57; commitid k8AY8I8nWyZ5F2OC; 1.57 date 2020.07.04.18.07.31; author riastradh; state Exp; branches 1.57.4.1; next 1.56; commitid cLYOYqSqCPbJ2NeC; 1.56 date 2020.06.29.23.34.48; author riastradh; state Exp; branches; next 1.55; commitid z3PzBArY7jlh2beC; 1.55 date 2020.06.14.23.23.55; author riastradh; state Exp; branches; next 1.54; commitid MSexab2MwXZrsfcC; 1.54 date 2019.10.12.00.49.30; author christos; state Exp; branches; next 1.53; commitid OSVYhSdQFXExRvGB; 1.53 date 2019.07.11.23.27.24; author christos; state Exp; branches; next 1.52; commitid vv7f91vAbwr6nGuB; 1.52 date 2017.06.23.11.41.58; author knakahara; state Exp; branches 1.52.6.1; next 1.51; commitid hqKfGlY9thnLvuWz; 1.51 date 2017.06.01.08.49.35; author knakahara; state Exp; branches 1.51.2.1; next 1.50; commitid XFWMmKAmOiOAgETz; 1.50 date 2017.05.17.06.33.04; author knakahara; state Exp; branches; next 1.49; commitid 0HVrot8rlDmyZHRz; 1.49 date 2017.04.18.17.05.05; author maya; state Exp; branches 1.49.2.1; next 1.48; commitid N2XFxH6j1ljCp2Oz; 1.48 date 2017.04.13.01.24.34; author ozaki-r; state Exp; branches; next 1.47; commitid tjMqTFlNBhRCnjNz; 1.47 date 2015.08.20.14.40.19; author christos; state Exp; branches 1.47.2.1 1.47.4.1; next 1.46; commitid xwHmhmQtB2Df81yy; 1.46 date 2014.07.02.18.58.42; author riastradh; state Exp; branches 1.46.4.1; next 1.45; commitid oxusLxm0WKi2SPGx; 1.45 date 2014.06.21.17.34.30; author christos; state Exp; branches; next 1.44; commitid Xj08vlOj8ET2LpFx; 1.44 date 2014.01.01.16.06.01; author pgoyette; state Exp; branches 1.44.2.1; next 1.43; commitid EnFHNUJmJQfnLqjx; 1.43 date 2013.09.12.13.12.35; author martin; state Exp; branches; next 1.42; commitid lr5lQ6rmFbtbn95x; 1.42 date 2013.06.24.04.21.20; author riastradh; state Exp; branches 1.42.2.1; next 1.41; commitid 6VKqBmjp9WKeZOUw; 1.41 date 2013.02.02.21.38.24; author christos; state Exp; branches; next 1.40; 1.40 date 2012.08.30.12.16.49; author drochner; state Exp; branches 1.40.2.1; next 1.39; 1.39 date 2011.11.28.08.05.06; author tls; state Exp; branches; next 1.38; 1.38 date 2011.06.07.15.57.51; author drochner; state Exp; branches 1.38.2.1; next 1.37; 1.37 date 2011.05.26.21.50.03; author drochner; state Exp; branches 1.37.2.1; next 1.36; 1.36 date 2011.05.24.19.10.10; author drochner; state Exp; branches; next 1.35; 1.35 date 2011.05.24.18.59.22; author drochner; state Exp; branches; next 1.34; 1.34 date 2011.05.24.18.52.51; author drochner; state Exp; branches; next 1.33; 1.33 date 2011.05.23.13.51.10; author drochner; state Exp; branches; next 1.32; 1.32 date 2011.05.23.13.46.54; author drochner; state Exp; branches; next 1.31; 1.31 date 2011.05.21.10.04.03; author drochner; state Exp; branches; next 1.30; 1.30 date 2011.05.05.17.44.39; author drochner; state Exp; branches; next 1.29; 1.29 date 2011.02.25.20.13.10; author drochner; state Exp; branches; next 1.28; 1.28 date 2011.02.24.20.03.41; author drochner; state Exp; branches; next 1.27; 1.27 date 2011.02.10.21.00.42; author drochner; state Exp; branches; next 1.26; 1.26 date 2010.08.02.19.59.35; author jakllsch; state Exp; branches 1.26.2.1 1.26.4.1; next 1.25; 1.25 date 2009.04.18.14.58.07; author tsutsui; state Exp; branches 1.25.2.1 1.25.4.1; next 1.24; 1.24 date 2009.03.25.01.26.13; author darran; state Exp; branches; next 1.23; 1.23 date 2009.03.18.17.06.53; author cegger; state Exp; branches; next 1.22; 1.22 date 2009.03.18.16.00.24; author cegger; state Exp; branches; next 1.21; 1.21 date 2008.12.17.20.51.38; author cegger; state Exp; branches 1.21.2.1; next 1.20; 1.20 date 2008.02.04.00.35.34; author tls; state Exp; branches 1.20.6.1 1.20.10.1 1.20.18.1 1.20.20.1 1.20.26.1; next 1.19; 1.19 date 2008.02.02.04.46.29; author tls; state Exp; branches; next 1.18; 1.18 date 2008.02.01.04.52.35; author tls; state Exp; branches; next 1.17; 1.17 date 2007.03.04.06.03.40; author christos; state Exp; branches 1.17.16.1 1.17.22.1; next 1.16; 1.16 date 2007.02.17.00.28.25; author daniel; state Exp; branches 1.16.2.1; next 1.15; 1.15 date 2006.11.16.01.33.51; author christos; state Exp; branches; next 1.14; 1.14 date 2006.10.12.01.32.47; author christos; state Exp; branches; next 1.13; 1.13 date 2006.04.02.18.29.12; author dsl; state Exp; branches 1.13.8.1 1.13.10.1; next 1.12; 1.12 date 2006.03.17.23.29.11; author christos; state Exp; branches; next 1.11; 1.11 date 2005.11.25.16.41.31; author thorpej; state Exp; branches 1.11.4.1 1.11.6.1 1.11.8.1 1.11.10.1 1.11.12.1; next 1.10; 1.10 date 2005.11.25.16.16.46; author thorpej; state Exp; branches; next 1.9; 1.9 date 2005.02.26.22.39.52; author perry; state Exp; branches 1.9.4.1 1.9.10.1; next 1.8; 1.8 date 2003.08.27.00.20.56; author thorpej; state Exp; branches 1.8.4.1 1.8.10.1 1.8.12.1; next 1.7; 1.7 date 2003.08.26.15.03.26; author thorpej; state Exp; branches; next 1.6; 1.6 date 2003.08.25.04.09.57; author thorpej; state Exp; branches; next 1.5; 1.5 date 2003.07.30.18.20.16; author jonathan; state Exp; branches; next 1.4; 1.4 date 2003.07.28.19.37.04; author jonathan; state Exp; branches; next 1.3; 1.3 date 2003.07.27.03.34.40; author jonathan; state Exp; branches; next 1.2; 1.2 date 2003.07.26.22.53.44; author jonathan; state Exp; branches; next 1.1; 1.1 date 2003.07.25.21.12.45; author jonathan; state Exp; branches; next ; 1.57.4.1 date 2021.04.17.17.26.22; author thorpej; state Exp; branches; next ; commitid bct79XL9ibnNBFPC; 1.52.6.1 date 2020.04.13.08.05.17; author martin; state Exp; branches; next ; commitid X01YhRUPVUDaec4C; 1.51.2.1 date 2017.07.05.20.19.21; author snj; state Exp; branches; next ; commitid FJ3kjquTMOBLY4Yz; 1.49.2.1 date 2017.05.17.01.44.18; author pgoyette; state Exp; branches; next 1.49.2.2; commitid rLOq5PM3VGZ1oGRz; 1.49.2.2 date 2017.05.19.00.22.58; author pgoyette; state Exp; branches; next ; commitid QNTxgGjVagwoSVRz; 1.47.2.1 date 2017.04.26.02.53.30; author pgoyette; state Exp; branches; next ; commitid ojV02aOSdzvBqZOz; 1.47.4.1 date 2017.04.21.16.54.07; author bouyer; state Exp; branches; next ; commitid dUG7nkTKALCadqOz; 1.46.4.1 date 2015.09.22.12.06.12; author skrll; state Exp; branches; next 1.46.4.2; commitid CpNWKp3ozVNTafCy; 1.46.4.2 date 2017.08.28.17.53.13; author skrll; state Exp; branches; next ; commitid UQQpnjvcNkUZn05A; 1.44.2.1 date 2014.08.10.06.56.47; author tls; state Exp; branches; next ; commitid uRqvBMYBs82FCMLx; 1.42.2.1 date 2014.05.18.17.46.14; author rmind; state Exp; branches; next ; commitid mL5ZYSzpqK6QS2Bx; 1.40.2.1 date 2013.02.25.00.30.07; author tls; state Exp; branches; next 1.40.2.2; 1.40.2.2 date 2014.08.20.00.04.36; author tls; state Exp; branches; next 1.40.2.3; commitid jTnpym9Qu0o4R1Nx; 1.40.2.3 date 2017.12.03.11.39.06; author jdolecek; state Exp; branches; next ; commitid XcIYRZTAh1LmerhA; 1.38.2.1 date 2012.04.17.00.08.48; author yamt; state Exp; branches; next 1.38.2.2; 1.38.2.2 date 2012.10.30.17.22.52; author yamt; state Exp; branches; next 1.38.2.3; 1.38.2.3 date 2014.05.22.11.41.11; author yamt; state Exp; branches; next ; commitid VUUXuyNWnt3AKwBx; 1.37.2.1 date 2011.06.23.14.20.28; author cherry; state Exp; branches; next ; 1.26.2.1 date 2011.06.06.09.10.03; author jruoho; state Exp; branches; next ; 1.26.4.1 date 2011.02.17.12.00.50; author bouyer; state Exp; branches; next 1.26.4.2; 1.26.4.2 date 2011.03.05.15.10.48; author bouyer; state Exp; branches; next ; 1.25.2.1 date 2010.08.17.06.47.52; author uebayasi; state Exp; branches; next ; 1.25.4.1 date 2011.03.05.20.56.05; author rmind; state Exp; branches; next 1.25.4.2; 1.25.4.2 date 2011.05.31.03.05.10; author rmind; state Exp; branches; next 1.25.4.3; 1.25.4.3 date 2011.06.12.00.24.31; author rmind; state Exp; branches; next ; 1.21.2.1 date 2009.05.13.17.22.56; author jym; state Exp; branches; next ; 1.20.6.1 date 2009.01.17.13.29.34; author mjf; state Exp; branches; next ; 1.20.10.1 date 2009.05.04.08.14.24; author yamt; state Exp; branches; next 1.20.10.2; 1.20.10.2 date 2010.08.11.22.54.59; author yamt; state Exp; branches; next ; 1.20.18.1 date 2009.01.19.13.20.20; author skrll; state Exp; branches; next 1.20.18.2; 1.20.18.2 date 2009.04.28.07.37.50; author skrll; state Exp; branches; next ; 1.20.20.1 date 2009.05.03.17.24.45; author snj; state Exp; branches; next ; 1.20.26.1 date 2011.05.20.08.11.32; author matt; state Exp; branches; next ; 1.17.16.1 date 2008.03.23.02.05.09; author matt; state Exp; branches; next ; 1.17.22.1 date 2008.02.18.21.07.18; author mjf; state Exp; branches; next ; 1.16.2.1 date 2007.02.17.00.28.25; author rmind; state dead; branches; next 1.16.2.2; 1.16.2.2 date 2007.03.12.06.00.50; author rmind; state Exp; branches; next ; 1.13.8.1 date 2006.11.18.21.39.44; author ad; state Exp; branches; next ; 1.13.10.1 date 2006.10.22.06.07.47; author yamt; state Exp; branches; next 1.13.10.2; 1.13.10.2 date 2006.12.10.07.19.28; author yamt; state Exp; branches; next ; 1.11.4.1 date 2006.09.09.02.59.41; author rpaulo; state Exp; branches; next ; 1.11.6.1 date 2006.04.22.11.40.18; author simonb; state Exp; branches; next ; 1.11.8.1 date 2006.04.01.12.07.51; author yamt; state Exp; branches; next 1.11.8.2; 1.11.8.2 date 2006.04.11.11.55.48; author yamt; state Exp; branches; next ; 1.11.10.1 date 2006.04.19.04.33.31; author elad; state Exp; branches; next ; 1.11.12.1 date 2006.03.28.09.42.28; author tron; state Exp; branches; next 1.11.12.2; 1.11.12.2 date 2006.05.24.15.50.47; author tron; state Exp; branches; next ; 1.9.4.1 date 2006.06.21.15.12.02; author yamt; state Exp; branches; next 1.9.4.2; 1.9.4.2 date 2007.02.26.09.12.08; author yamt; state Exp; branches; next 1.9.4.3; 1.9.4.3 date 2007.09.03.14.44.23; author yamt; state Exp; branches; next 1.9.4.4; 1.9.4.4 date 2008.02.04.09.24.47; author yamt; state Exp; branches; next ; 1.9.10.1 date 2005.11.29.21.23.33; author yamt; state Exp; branches; next ; 1.8.4.1 date 2003.08.27.00.20.56; author skrll; state dead; branches; next 1.8.4.2; 1.8.4.2 date 2004.08.03.10.56.25; author skrll; state Exp; branches; next 1.8.4.3; 1.8.4.3 date 2004.09.18.14.56.20; author skrll; state Exp; branches; next 1.8.4.4; 1.8.4.4 date 2004.09.21.13.38.44; author skrll; state Exp; branches; next 1.8.4.5; 1.8.4.5 date 2005.03.04.16.54.22; author skrll; state Exp; branches; next 1.8.4.6; 1.8.4.6 date 2005.12.11.10.29.36; author christos; state Exp; branches; next ; 1.8.10.1 date 2005.04.29.11.29.37; author kent; state Exp; branches; next ; 1.8.12.1 date 2005.03.19.08.36.52; author yamt; state Exp; branches; next ; desc @@ 1.64 log @opencrypto: Make freesession callback return void. No functional change intended: all drivers already return zero unconditionally. @ text @/* $NetBSD: cryptosoft.c,v 1.63 2022/05/22 11:38:59 riastradh Exp $ */ /* $FreeBSD: src/sys/opencrypto/cryptosoft.c,v 1.2.2.1 2002/11/21 23:34:23 sam Exp $ */ /* $OpenBSD: cryptosoft.c,v 1.35 2002/04/26 08:43:50 deraadt Exp $ */ /* * The author of this code is Angelos D. Keromytis (angelos@@cis.upenn.edu) * * This code was written by Angelos D. Keromytis in Athens, Greece, in * February 2000. Network Security Technologies Inc. (NSTI) kindly * supported the development of this code. * * Copyright (c) 2000, 2001 Angelos D. Keromytis * * Permission to use, copy, and modify this software with or without fee * is hereby granted, provided that this entire notice is included in * all source code copies of any software which is or includes a copy or * modification of this software. * * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR * PURPOSE. */ #include __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.63 2022/05/22 11:38:59 riastradh Exp $"); #include #include #include #include #include #include #include #include #include #ifdef _KERNEL_OPT #include "opt_ocf.h" #endif #include #include #include #include #include "ioconf.h" union authctx { MD5_CTX md5ctx; SHA1_CTX sha1ctx; RMD160_CTX rmd160ctx; SHA256_CTX sha256ctx; SHA384_CTX sha384ctx; SHA512_CTX sha512ctx; aesxcbc_ctx aesxcbcctx; AES_GMAC_CTX aesgmacctx; }; struct swcr_data **swcr_sessions = NULL; u_int32_t swcr_sesnum = 0; int32_t swcr_id = -1; #define COPYBACK(x, a, b, c, d) \ (x) == CRYPTO_BUF_MBUF ? m_copyback((struct mbuf *)a,b,c,d) \ : cuio_copyback((struct uio *)a,b,c,d) #define COPYDATA(x, a, b, c, d) \ (x) == CRYPTO_BUF_MBUF ? m_copydata((struct mbuf *)a,b,c,d) \ : cuio_copydata((struct uio *)a,b,c,d) static int swcr_encdec(struct cryptodesc *, const struct swcr_data *, void *, int); static int swcr_compdec(struct cryptodesc *, const struct swcr_data *, void *, int, int *); static int swcr_combined(struct cryptop *, int); static int swcr_process(void *, struct cryptop *, int); static int swcr_newsession(void *, u_int32_t *, struct cryptoini *); static void swcr_freesession(void *, u_int64_t); static void swcr_freesession_internal(struct swcr_data *); static int swcryptoattach_internal(void); /* * Apply a symmetric encryption/decryption algorithm. */ static int swcr_encdec(struct cryptodesc *crd, const struct swcr_data *sw, void *bufv, int outtype) { char *buf = bufv; unsigned char iv[EALG_MAX_BLOCK_LEN], blk[EALG_MAX_BLOCK_LEN], *idat; unsigned char *ivp, piv[EALG_MAX_BLOCK_LEN]; const struct swcr_enc_xform *exf; int i, k, j, blks, ivlen; int count, ind; exf = sw->sw_exf; blks = exf->enc_xform->blocksize; ivlen = exf->enc_xform->ivsize; KASSERT(exf->reinit ? ivlen <= blks : ivlen == blks); /* Check for non-padded data */ if (crd->crd_len % blks) return EINVAL; /* Initialize the IV */ if (crd->crd_flags & CRD_F_ENCRYPT) { /* IV explicitly provided ? */ if (crd->crd_flags & CRD_F_IV_EXPLICIT) { memcpy(iv, crd->crd_iv, ivlen); if (exf->reinit) exf->reinit(sw->sw_kschedule, iv, 0); } else if (exf->reinit) { exf->reinit(sw->sw_kschedule, 0, iv); } else { cprng_fast(iv, EALG_MAX_BLOCK_LEN); } /* Do we need to write the IV */ if (!(crd->crd_flags & CRD_F_IV_PRESENT)) { COPYBACK(outtype, buf, crd->crd_inject, ivlen, iv); } } else { /* Decryption */ /* IV explicitly provided ? */ if (crd->crd_flags & CRD_F_IV_EXPLICIT) memcpy(iv, crd->crd_iv, ivlen); else { /* Get IV off buf */ COPYDATA(outtype, buf, crd->crd_inject, ivlen, iv); } if (exf->reinit) exf->reinit(sw->sw_kschedule, iv, 0); } ivp = iv; if (outtype == CRYPTO_BUF_CONTIG) { if (exf->reinit) { for (i = crd->crd_skip; i < crd->crd_skip + crd->crd_len; i += blks) { if (crd->crd_flags & CRD_F_ENCRYPT) { exf->encrypt(sw->sw_kschedule, buf + i); } else { exf->decrypt(sw->sw_kschedule, buf + i); } } } else if (crd->crd_flags & CRD_F_ENCRYPT) { for (i = crd->crd_skip; i < crd->crd_skip + crd->crd_len; i += blks) { /* XOR with the IV/previous block, as appropriate. */ if (i == crd->crd_skip) for (k = 0; k < blks; k++) buf[i + k] ^= ivp[k]; else for (k = 0; k < blks; k++) buf[i + k] ^= buf[i + k - blks]; exf->encrypt(sw->sw_kschedule, buf + i); } } else { /* Decrypt */ /* * Start at the end, so we don't need to keep the encrypted * block as the IV for the next block. */ for (i = crd->crd_skip + crd->crd_len - blks; i >= crd->crd_skip; i -= blks) { exf->decrypt(sw->sw_kschedule, buf + i); /* XOR with the IV/previous block, as appropriate */ if (i == crd->crd_skip) for (k = 0; k < blks; k++) buf[i + k] ^= ivp[k]; else for (k = 0; k < blks; k++) buf[i + k] ^= buf[i + k - blks]; } } return 0; } else if (outtype == CRYPTO_BUF_MBUF) { struct mbuf *m = (struct mbuf *) buf; /* Find beginning of data */ m = m_getptr(m, crd->crd_skip, &k); if (m == NULL) return EINVAL; i = crd->crd_len; while (i > 0) { /* * If there's insufficient data at the end of * an mbuf, we have to do some copying. */ if (m->m_len < k + blks && m->m_len != k) { m_copydata(m, k, blks, blk); /* Actual encryption/decryption */ if (exf->reinit) { if (crd->crd_flags & CRD_F_ENCRYPT) { exf->encrypt(sw->sw_kschedule, blk); } else { exf->decrypt(sw->sw_kschedule, blk); } } else if (crd->crd_flags & CRD_F_ENCRYPT) { /* XOR with previous block */ for (j = 0; j < blks; j++) blk[j] ^= ivp[j]; exf->encrypt(sw->sw_kschedule, blk); /* * Keep encrypted block for XOR'ing * with next block */ memcpy(iv, blk, blks); ivp = iv; } else { /* decrypt */ /* * Keep encrypted block for XOR'ing * with next block */ if (ivp == iv) memcpy(piv, blk, blks); else memcpy(iv, blk, blks); exf->decrypt(sw->sw_kschedule, blk); /* XOR with previous block */ for (j = 0; j < blks; j++) blk[j] ^= ivp[j]; if (ivp == iv) memcpy(iv, piv, blks); else ivp = iv; } /* Copy back decrypted block */ m_copyback(m, k, blks, blk); /* Advance pointer */ m = m_getptr(m, k + blks, &k); if (m == NULL) return EINVAL; i -= blks; /* Could be done... */ if (i == 0) break; } /* Skip possibly empty mbufs */ if (k == m->m_len) { for (m = m->m_next; m && m->m_len == 0; m = m->m_next) ; k = 0; } /* Sanity check */ if (m == NULL) return EINVAL; /* * Warning: idat may point to garbage here, but * we only use it in the while() loop, only if * there are indeed enough data. */ idat = mtod(m, unsigned char *) + k; while (m->m_len >= k + blks && i > 0) { if (exf->reinit) { if (crd->crd_flags & CRD_F_ENCRYPT) { exf->encrypt(sw->sw_kschedule, idat); } else { exf->decrypt(sw->sw_kschedule, idat); } } else if (crd->crd_flags & CRD_F_ENCRYPT) { /* XOR with previous block/IV */ for (j = 0; j < blks; j++) idat[j] ^= ivp[j]; exf->encrypt(sw->sw_kschedule, idat); ivp = idat; } else { /* decrypt */ /* * Keep encrypted block to be used * in next block's processing. */ if (ivp == iv) memcpy(piv, idat, blks); else memcpy(iv, idat, blks); exf->decrypt(sw->sw_kschedule, idat); /* XOR with previous block/IV */ for (j = 0; j < blks; j++) idat[j] ^= ivp[j]; if (ivp == iv) memcpy(iv, piv, blks); else ivp = iv; } idat += blks; k += blks; i -= blks; } } return 0; /* Done with mbuf encryption/decryption */ } else if (outtype == CRYPTO_BUF_IOV) { struct uio *uio = (struct uio *) buf; /* Find beginning of data */ count = crd->crd_skip; ind = cuio_getptr(uio, count, &k); if (ind == -1) return EINVAL; i = crd->crd_len; while (i > 0) { /* * If there's insufficient data at the end, * we have to do some copying. */ if (uio->uio_iov[ind].iov_len < k + blks && uio->uio_iov[ind].iov_len != k) { cuio_copydata(uio, k, blks, blk); /* Actual encryption/decryption */ if (exf->reinit) { if (crd->crd_flags & CRD_F_ENCRYPT) { exf->encrypt(sw->sw_kschedule, blk); } else { exf->decrypt(sw->sw_kschedule, blk); } } else if (crd->crd_flags & CRD_F_ENCRYPT) { /* XOR with previous block */ for (j = 0; j < blks; j++) blk[j] ^= ivp[j]; exf->encrypt(sw->sw_kschedule, blk); /* * Keep encrypted block for XOR'ing * with next block */ memcpy(iv, blk, blks); ivp = iv; } else { /* decrypt */ /* * Keep encrypted block for XOR'ing * with next block */ if (ivp == iv) memcpy(piv, blk, blks); else memcpy(iv, blk, blks); exf->decrypt(sw->sw_kschedule, blk); /* XOR with previous block */ for (j = 0; j < blks; j++) blk[j] ^= ivp[j]; if (ivp == iv) memcpy(iv, piv, blks); else ivp = iv; } /* Copy back decrypted block */ cuio_copyback(uio, k, blks, blk); count += blks; /* Advance pointer */ ind = cuio_getptr(uio, count, &k); if (ind == -1) return (EINVAL); i -= blks; /* Could be done... */ if (i == 0) break; } /* * Warning: idat may point to garbage here, but * we only use it in the while() loop, only if * there are indeed enough data. */ idat = ((char *)uio->uio_iov[ind].iov_base) + k; while (uio->uio_iov[ind].iov_len >= k + blks && i > 0) { if (exf->reinit) { if (crd->crd_flags & CRD_F_ENCRYPT) { exf->encrypt(sw->sw_kschedule, idat); } else { exf->decrypt(sw->sw_kschedule, idat); } } else if (crd->crd_flags & CRD_F_ENCRYPT) { /* XOR with previous block/IV */ for (j = 0; j < blks; j++) idat[j] ^= ivp[j]; exf->encrypt(sw->sw_kschedule, idat); ivp = idat; } else { /* decrypt */ /* * Keep encrypted block to be used * in next block's processing. */ if (ivp == iv) memcpy(piv, idat, blks); else memcpy(iv, idat, blks); exf->decrypt(sw->sw_kschedule, idat); /* XOR with previous block/IV */ for (j = 0; j < blks; j++) idat[j] ^= ivp[j]; if (ivp == iv) memcpy(iv, piv, blks); else ivp = iv; } idat += blks; count += blks; k += blks; i -= blks; } } return 0; /* Done with mbuf encryption/decryption */ } /* Unreachable */ return EINVAL; } /* * Compute keyed-hash authenticator. */ int swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd, const struct swcr_data *sw, void *buf, int outtype) { unsigned char aalg[AALG_MAX_RESULT_LEN]; const struct swcr_auth_hash *axf; union authctx ctx; int err; if (sw->sw_ictx == 0) return EINVAL; axf = sw->sw_axf; memcpy(&ctx, sw->sw_ictx, axf->ctxsize); switch (outtype) { case CRYPTO_BUF_CONTIG: axf->Update(&ctx, (char *)buf + crd->crd_skip, crd->crd_len); break; case CRYPTO_BUF_MBUF: err = m_apply((struct mbuf *) buf, crd->crd_skip, crd->crd_len, (int (*)(void*, void *, unsigned int))(void *)axf->Update, (void *) &ctx); if (err) return err; break; case CRYPTO_BUF_IOV: err = cuio_apply((struct uio *) buf, crd->crd_skip, crd->crd_len, (int (*)(void *, void *, unsigned int))(void *)axf->Update, (void *) &ctx); if (err) { return err; } break; default: return EINVAL; } switch (sw->sw_alg) { case CRYPTO_MD5_HMAC: case CRYPTO_MD5_HMAC_96: case CRYPTO_SHA1_HMAC: case CRYPTO_SHA1_HMAC_96: case CRYPTO_SHA2_256_HMAC: case CRYPTO_SHA2_384_HMAC: case CRYPTO_SHA2_512_HMAC: case CRYPTO_RIPEMD160_HMAC: case CRYPTO_RIPEMD160_HMAC_96: if (sw->sw_octx == NULL) return EINVAL; axf->Final(aalg, &ctx); memcpy(&ctx, sw->sw_octx, axf->ctxsize); axf->Update(&ctx, aalg, axf->auth_hash->hashsize); axf->Final(aalg, &ctx); break; case CRYPTO_MD5_KPDK: case CRYPTO_SHA1_KPDK: if (sw->sw_octx == NULL) return EINVAL; axf->Update(&ctx, sw->sw_octx, sw->sw_klen); axf->Final(aalg, &ctx); break; case CRYPTO_NULL_HMAC: case CRYPTO_MD5: case CRYPTO_SHA1: case CRYPTO_AES_XCBC_MAC_96: axf->Final(aalg, &ctx); break; } /* Inject the authentication data */ switch (outtype) { case CRYPTO_BUF_CONTIG: (void)memcpy((char *)buf + crd->crd_inject, aalg, axf->auth_hash->authsize); break; case CRYPTO_BUF_MBUF: m_copyback((struct mbuf *) buf, crd->crd_inject, axf->auth_hash->authsize, aalg); break; case CRYPTO_BUF_IOV: memcpy(crp->crp_mac, aalg, axf->auth_hash->authsize); break; default: return EINVAL; } return 0; } /* * Apply a combined encryption-authentication transformation */ static int swcr_combined(struct cryptop *crp, int outtype) { uint32_t blkbuf[howmany(EALG_MAX_BLOCK_LEN, sizeof(uint32_t))]; u_char *blk = (u_char *)blkbuf; u_char aalg[AALG_MAX_RESULT_LEN]; u_char iv[EALG_MAX_BLOCK_LEN]; union authctx ctx; struct cryptodesc *crd, *crda = NULL, *crde = NULL; struct swcr_data *sw, *swa, *swe = NULL; const struct swcr_auth_hash *axf = NULL; const struct swcr_enc_xform *exf = NULL; void *buf = (void *)crp->crp_buf; uint32_t *blkp; int i, blksz = 0, ivlen = 0, len; for (crd = crp->crp_desc; crd; crd = crd->crd_next) { for (sw = swcr_sessions[crp->crp_sid & 0xffffffff]; sw && sw->sw_alg != crd->crd_alg; sw = sw->sw_next) ; if (sw == NULL) return (EINVAL); switch (sw->sw_alg) { case CRYPTO_AES_GCM_16: case CRYPTO_AES_GMAC: swe = sw; crde = crd; exf = swe->sw_exf; ivlen = exf->enc_xform->ivsize; break; case CRYPTO_AES_128_GMAC: case CRYPTO_AES_192_GMAC: case CRYPTO_AES_256_GMAC: swa = sw; crda = crd; axf = swa->sw_axf; if (swa->sw_ictx == 0) return (EINVAL); memcpy(&ctx, swa->sw_ictx, axf->ctxsize); blksz = axf->auth_hash->blocksize; break; default: return (EINVAL); } } if (crde == NULL || crda == NULL) return (EINVAL); if (outtype == CRYPTO_BUF_CONTIG) return (EINVAL); /* Initialize the IV */ if (crde->crd_flags & CRD_F_ENCRYPT) { /* IV explicitly provided ? */ if (crde->crd_flags & CRD_F_IV_EXPLICIT) { memcpy(iv, crde->crd_iv, ivlen); if (exf->reinit) exf->reinit(swe->sw_kschedule, iv, 0); } else if (exf->reinit) exf->reinit(swe->sw_kschedule, 0, iv); else cprng_fast(iv, ivlen); /* Do we need to write the IV */ if (!(crde->crd_flags & CRD_F_IV_PRESENT)) COPYBACK(outtype, buf, crde->crd_inject, ivlen, iv); } else { /* Decryption */ /* IV explicitly provided ? */ if (crde->crd_flags & CRD_F_IV_EXPLICIT) memcpy(iv, crde->crd_iv, ivlen); else { /* Get IV off buf */ COPYDATA(outtype, buf, crde->crd_inject, ivlen, iv); } if (exf->reinit) exf->reinit(swe->sw_kschedule, iv, 0); } /* Supply MAC with IV */ if (axf->Reinit) axf->Reinit(&ctx, iv, ivlen); /* Supply MAC with AAD */ for (i = 0; i < crda->crd_len; i += blksz) { len = MIN(crda->crd_len - i, blksz); COPYDATA(outtype, buf, crda->crd_skip + i, len, blk); axf->Update(&ctx, blk, len); } /* Do encryption/decryption with MAC */ for (i = 0; i < crde->crd_len; i += blksz) { len = MIN(crde->crd_len - i, blksz); if (len < blksz) memset(blk, 0, blksz); COPYDATA(outtype, buf, crde->crd_skip + i, len, blk); if (crde->crd_flags & CRD_F_ENCRYPT) { exf->encrypt(swe->sw_kschedule, blk); axf->Update(&ctx, blk, len); } else { axf->Update(&ctx, blk, len); exf->decrypt(swe->sw_kschedule, blk); } COPYBACK(outtype, buf, crde->crd_skip + i, len, blk); } /* Do any required special finalization */ switch (crda->crd_alg) { case CRYPTO_AES_128_GMAC: case CRYPTO_AES_192_GMAC: case CRYPTO_AES_256_GMAC: /* length block */ memset(blk, 0, blksz); blkp = (uint32_t *)blk + 1; *blkp = htobe32(crda->crd_len * 8); blkp = (uint32_t *)blk + 3; *blkp = htobe32(crde->crd_len * 8); axf->Update(&ctx, blk, blksz); break; } /* Finalize MAC */ axf->Final(aalg, &ctx); /* Inject the authentication data */ if (outtype == CRYPTO_BUF_MBUF) COPYBACK(outtype, buf, crda->crd_inject, axf->auth_hash->authsize, aalg); else memcpy(crp->crp_mac, aalg, axf->auth_hash->authsize); return (0); } /* * Apply a compression/decompression algorithm */ static int swcr_compdec(struct cryptodesc *crd, const struct swcr_data *sw, void *buf, int outtype, int *res_size) { u_int8_t *data, *out; const struct swcr_comp_algo *cxf; int adj; u_int32_t result; cxf = sw->sw_cxf; /* We must handle the whole buffer of data in one time * then if there is not all the data in the mbuf, we must * copy in a buffer. */ data = malloc(crd->crd_len, M_CRYPTO_DATA, M_NOWAIT); if (data == NULL) return (EINVAL); COPYDATA(outtype, buf, crd->crd_skip, crd->crd_len, data); if (crd->crd_flags & CRD_F_COMP) result = cxf->compress(data, crd->crd_len, &out); else result = cxf->decompress(data, crd->crd_len, &out, *res_size); free(data, M_CRYPTO_DATA); if (result == 0) return EINVAL; /* Copy back the (de)compressed data. m_copyback is * extending the mbuf as necessary. */ *res_size = (int)result; /* Check the compressed size when doing compression */ if (crd->crd_flags & CRD_F_COMP && sw->sw_alg == CRYPTO_DEFLATE_COMP_NOGROW && result >= crd->crd_len) { /* Compression was useless, we lost time */ free(out, M_CRYPTO_DATA); return 0; } COPYBACK(outtype, buf, crd->crd_skip, result, out); if (result < crd->crd_len) { adj = result - crd->crd_len; if (outtype == CRYPTO_BUF_MBUF) { m_adj((struct mbuf *)buf, adj); } /* Don't adjust the iov_len, it breaks the kmem_free */ } free(out, M_CRYPTO_DATA); return 0; } /* * Generate a new software session. */ static int swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri) { struct swcr_data **swd; struct swcr_data *first, *tmp; const struct swcr_auth_hash *axf; const struct swcr_enc_xform *txf; const struct swcr_comp_algo *cxf; u_int32_t i; int k, error; if (swcr_sessions) { for (i = 1; i < swcr_sesnum; i++) if (swcr_sessions[i] == NULL) break; } else i = 1; /* NB: to silence compiler warning */ if (swcr_sessions == NULL || i == swcr_sesnum) { u_int32_t newnum; struct swcr_data **newsessions; if (swcr_sessions == NULL) { i = 1; /* We leave swcr_sessions[0] empty */ newnum = CRYPTO_SW_SESSIONS; } else newnum = swcr_sesnum *= 2; newsessions = kmem_zalloc(newnum * sizeof(struct swcr_data *), KM_NOSLEEP); if (newsessions == NULL) { return ENOBUFS; } /* Copy existing sessions */ if (swcr_sessions) { memcpy(newsessions, swcr_sessions, swcr_sesnum * sizeof(struct swcr_data *)); kmem_free(swcr_sessions, swcr_sesnum * sizeof(struct swcr_data *)); } swcr_sesnum = newnum; swcr_sessions = newsessions; } first = NULL; swd = &tmp; while (cri) { *swd = kmem_zalloc(sizeof **swd, KM_NOSLEEP); if (*swd == NULL) { if (first != NULL) swcr_freesession_internal(first); return ENOBUFS; } else if (first == NULL) first = *swd; switch (cri->cri_alg) { case CRYPTO_DES_CBC: txf = &swcr_enc_xform_des; goto enccommon; case CRYPTO_3DES_CBC: txf = &swcr_enc_xform_3des; goto enccommon; case CRYPTO_BLF_CBC: txf = &swcr_enc_xform_blf; goto enccommon; case CRYPTO_CAST_CBC: txf = &swcr_enc_xform_cast5; goto enccommon; case CRYPTO_SKIPJACK_CBC: txf = &swcr_enc_xform_skipjack; goto enccommon; case CRYPTO_AES_CBC: txf = &swcr_enc_xform_aes; goto enccommon; case CRYPTO_CAMELLIA_CBC: txf = &swcr_enc_xform_camellia; goto enccommon; case CRYPTO_AES_CTR: txf = &swcr_enc_xform_aes_ctr; goto enccommon; case CRYPTO_AES_GCM_16: txf = &swcr_enc_xform_aes_gcm; goto enccommon; case CRYPTO_AES_GMAC: txf = &swcr_enc_xform_aes_gmac; goto enccommon; case CRYPTO_NULL_CBC: txf = &swcr_enc_xform_null; goto enccommon; enccommon: error = txf->setkey(&((*swd)->sw_kschedule), cri->cri_key, cri->cri_klen / 8); if (error) { swcr_freesession_internal(first); return error; } (*swd)->sw_exf = txf; break; case CRYPTO_MD5_HMAC: axf = &swcr_auth_hash_hmac_md5; goto authcommon; case CRYPTO_MD5_HMAC_96: axf = &swcr_auth_hash_hmac_md5_96; goto authcommon; case CRYPTO_SHA1_HMAC: axf = &swcr_auth_hash_hmac_sha1; goto authcommon; case CRYPTO_SHA1_HMAC_96: axf = &swcr_auth_hash_hmac_sha1_96; goto authcommon; case CRYPTO_SHA2_256_HMAC: axf = &swcr_auth_hash_hmac_sha2_256; goto authcommon; case CRYPTO_SHA2_384_HMAC: axf = &swcr_auth_hash_hmac_sha2_384; goto authcommon; case CRYPTO_SHA2_512_HMAC: axf = &swcr_auth_hash_hmac_sha2_512; goto authcommon; case CRYPTO_NULL_HMAC: axf = &swcr_auth_hash_null; goto authcommon; case CRYPTO_RIPEMD160_HMAC: axf = &swcr_auth_hash_hmac_ripemd_160; goto authcommon; case CRYPTO_RIPEMD160_HMAC_96: axf = &swcr_auth_hash_hmac_ripemd_160_96; goto authcommon; /* leave this for safety */ authcommon: (*swd)->sw_ictx = kmem_alloc(axf->ctxsize, KM_NOSLEEP); if ((*swd)->sw_ictx == NULL) { swcr_freesession_internal(first); return ENOBUFS; } (*swd)->sw_octx = kmem_alloc(axf->ctxsize, KM_NOSLEEP); if ((*swd)->sw_octx == NULL) { swcr_freesession_internal(first); return ENOBUFS; } for (k = 0; k < cri->cri_klen / 8; k++) cri->cri_key[k] ^= HMAC_IPAD_VAL; axf->Init((*swd)->sw_ictx); axf->Update((*swd)->sw_ictx, cri->cri_key, cri->cri_klen / 8); axf->Update((*swd)->sw_ictx, hmac_ipad_buffer, axf->auth_hash->blocksize - (cri->cri_klen / 8)); for (k = 0; k < cri->cri_klen / 8; k++) cri->cri_key[k] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL); axf->Init((*swd)->sw_octx); axf->Update((*swd)->sw_octx, cri->cri_key, cri->cri_klen / 8); axf->Update((*swd)->sw_octx, hmac_opad_buffer, axf->auth_hash->blocksize - (cri->cri_klen / 8)); for (k = 0; k < cri->cri_klen / 8; k++) cri->cri_key[k] ^= HMAC_OPAD_VAL; (*swd)->sw_axf = axf; break; case CRYPTO_MD5_KPDK: axf = &swcr_auth_hash_key_md5; goto auth2common; case CRYPTO_SHA1_KPDK: { unsigned char digest[SHA1_DIGEST_LENGTH]; CTASSERT(SHA1_DIGEST_LENGTH >= MD5_DIGEST_LENGTH); axf = &swcr_auth_hash_key_sha1; auth2common: (*swd)->sw_ictx = kmem_alloc(axf->ctxsize, KM_NOSLEEP); if ((*swd)->sw_ictx == NULL) { swcr_freesession_internal(first); return ENOBUFS; } /* Store the key so we can "append" it to the payload */ (*swd)->sw_octx = kmem_alloc(cri->cri_klen / 8, KM_NOSLEEP); if ((*swd)->sw_octx == NULL) { swcr_freesession_internal(first); return ENOBUFS; } (*swd)->sw_klen = cri->cri_klen / 8; memcpy((*swd)->sw_octx, cri->cri_key, cri->cri_klen / 8); axf->Init((*swd)->sw_ictx); axf->Update((*swd)->sw_ictx, cri->cri_key, cri->cri_klen / 8); axf->Final(digest, (*swd)->sw_ictx); (*swd)->sw_axf = axf; break; } case CRYPTO_MD5: axf = &swcr_auth_hash_md5; goto auth3common; case CRYPTO_SHA1: axf = &swcr_auth_hash_sha1; auth3common: (*swd)->sw_ictx = kmem_alloc(axf->ctxsize, KM_NOSLEEP); if ((*swd)->sw_ictx == NULL) { swcr_freesession_internal(first); return ENOBUFS; } axf->Init((*swd)->sw_ictx); (*swd)->sw_axf = axf; break; case CRYPTO_AES_XCBC_MAC_96: axf = &swcr_auth_hash_aes_xcbc_mac; goto auth4common; case CRYPTO_AES_128_GMAC: axf = &swcr_auth_hash_gmac_aes_128; goto auth4common; case CRYPTO_AES_192_GMAC: axf = &swcr_auth_hash_gmac_aes_192; goto auth4common; case CRYPTO_AES_256_GMAC: axf = &swcr_auth_hash_gmac_aes_256; auth4common: (*swd)->sw_ictx = kmem_alloc(axf->ctxsize, KM_NOSLEEP); if ((*swd)->sw_ictx == NULL) { swcr_freesession_internal(first); return ENOBUFS; } axf->Init((*swd)->sw_ictx); axf->Setkey((*swd)->sw_ictx, cri->cri_key, cri->cri_klen / 8); (*swd)->sw_axf = axf; break; case CRYPTO_DEFLATE_COMP: cxf = &swcr_comp_algo_deflate; (*swd)->sw_cxf = cxf; break; case CRYPTO_DEFLATE_COMP_NOGROW: cxf = &swcr_comp_algo_deflate_nogrow; (*swd)->sw_cxf = cxf; break; case CRYPTO_GZIP_COMP: cxf = &swcr_comp_algo_gzip; (*swd)->sw_cxf = cxf; break; default: swcr_freesession_internal(first); return EINVAL; } (*swd)->sw_alg = cri->cri_alg; cri = cri->cri_next; swd = &((*swd)->sw_next); } swcr_sessions[i] = first; *sid = i; return 0; } static void swcr_freesession_internal(struct swcr_data *arg) { struct swcr_data *swd, *swd0; const struct swcr_enc_xform *txf; const struct swcr_auth_hash *axf; if (arg == NULL) return; swd0 = arg; while ((swd = swd0) != NULL) { swd0 = swd->sw_next; switch (swd->sw_alg) { case CRYPTO_DES_CBC: case CRYPTO_3DES_CBC: case CRYPTO_BLF_CBC: case CRYPTO_CAST_CBC: case CRYPTO_SKIPJACK_CBC: case CRYPTO_AES_CBC: case CRYPTO_CAMELLIA_CBC: case CRYPTO_AES_CTR: case CRYPTO_AES_GCM_16: case CRYPTO_AES_GMAC: case CRYPTO_NULL_CBC: txf = swd->sw_exf; if (swd->sw_kschedule) txf->zerokey(&(swd->sw_kschedule)); break; case CRYPTO_MD5_HMAC: case CRYPTO_MD5_HMAC_96: case CRYPTO_SHA1_HMAC: case CRYPTO_SHA1_HMAC_96: case CRYPTO_SHA2_256_HMAC: case CRYPTO_SHA2_384_HMAC: case CRYPTO_SHA2_512_HMAC: case CRYPTO_RIPEMD160_HMAC: case CRYPTO_RIPEMD160_HMAC_96: case CRYPTO_NULL_HMAC: axf = swd->sw_axf; if (swd->sw_ictx) { explicit_memset(swd->sw_ictx, 0, axf->ctxsize); kmem_free(swd->sw_ictx, axf->ctxsize); } if (swd->sw_octx) { explicit_memset(swd->sw_octx, 0, axf->ctxsize); kmem_free(swd->sw_octx, axf->ctxsize); } break; case CRYPTO_MD5_KPDK: case CRYPTO_SHA1_KPDK: axf = swd->sw_axf; if (swd->sw_ictx) { explicit_memset(swd->sw_ictx, 0, axf->ctxsize); kmem_free(swd->sw_ictx, axf->ctxsize); } if (swd->sw_octx) { explicit_memset(swd->sw_octx, 0, swd->sw_klen); kmem_free(swd->sw_octx, swd->sw_klen); } break; case CRYPTO_MD5: case CRYPTO_SHA1: case CRYPTO_AES_XCBC_MAC_96: case CRYPTO_AES_128_GMAC: case CRYPTO_AES_192_GMAC: case CRYPTO_AES_256_GMAC: axf = swd->sw_axf; if (swd->sw_ictx) { explicit_memset(swd->sw_ictx, 0, axf->ctxsize); kmem_free(swd->sw_ictx, axf->ctxsize); } break; case CRYPTO_DEFLATE_COMP: case CRYPTO_DEFLATE_COMP_NOGROW: case CRYPTO_GZIP_COMP: break; } kmem_free(swd, sizeof(*swd)); } } /* * Free a session. */ static void swcr_freesession(void *arg, u_int64_t tid) { struct swcr_data *swd; u_int32_t sid = ((u_int32_t) tid) & 0xffffffff; KASSERTMSG(sid < swcr_sesnum, "sid=%"PRIu32" swcr_sesnum=%"PRIu32, sid, swcr_sesnum); KASSERT(swcr_sessions[sid]); swd = swcr_sessions[sid]; swcr_sessions[sid] = NULL; swcr_freesession_internal(swd); } /* * Process a software request. */ static int swcr_process(void *arg, struct cryptop *crp, int hint) { struct cryptodesc *crd; struct swcr_data *sw; u_int32_t lid; int type; /* Sanity check */ if (crp == NULL) return EINVAL; if (crp->crp_desc == NULL || crp->crp_buf == NULL) { crp->crp_etype = EINVAL; goto done; } lid = crp->crp_sid & 0xffffffff; if (lid >= swcr_sesnum || lid == 0 || swcr_sessions[lid] == NULL) { crp->crp_etype = ENOENT; goto done; } if (crp->crp_flags & CRYPTO_F_IMBUF) { type = CRYPTO_BUF_MBUF; } else if (crp->crp_flags & CRYPTO_F_IOV) { type = CRYPTO_BUF_IOV; } else { type = CRYPTO_BUF_CONTIG; } /* Go through crypto descriptors, processing as we go */ for (crd = crp->crp_desc; crd; crd = crd->crd_next) { /* * Find the crypto context. * * XXX Note that the logic here prevents us from having * XXX the same algorithm multiple times in a session * XXX (or rather, we can but it won't give us the right * XXX results). To do that, we'd need some way of differentiating * XXX between the various instances of an algorithm (so we can * XXX locate the correct crypto context). */ for (sw = swcr_sessions[lid]; sw && sw->sw_alg != crd->crd_alg; sw = sw->sw_next) ; /* No such context ? */ if (sw == NULL) { crp->crp_etype = EINVAL; goto done; } switch (sw->sw_alg) { case CRYPTO_DES_CBC: case CRYPTO_3DES_CBC: case CRYPTO_BLF_CBC: case CRYPTO_CAST_CBC: case CRYPTO_SKIPJACK_CBC: case CRYPTO_AES_CBC: case CRYPTO_CAMELLIA_CBC: case CRYPTO_AES_CTR: if ((crp->crp_etype = swcr_encdec(crd, sw, crp->crp_buf, type)) != 0) goto done; break; case CRYPTO_NULL_CBC: crp->crp_etype = 0; break; case CRYPTO_MD5_HMAC: case CRYPTO_MD5_HMAC_96: case CRYPTO_SHA1_HMAC: case CRYPTO_SHA1_HMAC_96: case CRYPTO_SHA2_256_HMAC: case CRYPTO_SHA2_384_HMAC: case CRYPTO_SHA2_512_HMAC: case CRYPTO_RIPEMD160_HMAC: case CRYPTO_RIPEMD160_HMAC_96: case CRYPTO_NULL_HMAC: case CRYPTO_MD5_KPDK: case CRYPTO_SHA1_KPDK: case CRYPTO_MD5: case CRYPTO_SHA1: case CRYPTO_AES_XCBC_MAC_96: if ((crp->crp_etype = swcr_authcompute(crp, crd, sw, crp->crp_buf, type)) != 0) goto done; break; case CRYPTO_AES_GCM_16: case CRYPTO_AES_GMAC: case CRYPTO_AES_128_GMAC: case CRYPTO_AES_192_GMAC: case CRYPTO_AES_256_GMAC: crp->crp_etype = swcr_combined(crp, type); goto done; case CRYPTO_DEFLATE_COMP: case CRYPTO_DEFLATE_COMP_NOGROW: case CRYPTO_GZIP_COMP: DPRINTF("compdec for %d\n", sw->sw_alg); if ((crp->crp_etype = swcr_compdec(crd, sw, crp->crp_buf, type, &crp->crp_olen)) != 0) goto done; break; default: /* Unknown/unsupported algorithm */ crp->crp_etype = EINVAL; goto done; } } done: DPRINTF("request %p done\n", crp); crypto_done(crp); return 0; } static void swcr_init(void) { swcr_id = crypto_get_driverid(CRYPTOCAP_F_SOFTWARE); if (swcr_id < 0) { /* This should never happen */ panic("Software crypto device cannot initialize!"); } crypto_register(swcr_id, CRYPTO_DES_CBC, 0, 0, swcr_newsession, swcr_freesession, swcr_process, NULL); #define REGISTER(alg) \ crypto_register(swcr_id, alg, 0, 0, NULL, NULL, NULL, NULL) REGISTER(CRYPTO_3DES_CBC); REGISTER(CRYPTO_BLF_CBC); REGISTER(CRYPTO_CAST_CBC); REGISTER(CRYPTO_SKIPJACK_CBC); REGISTER(CRYPTO_CAMELLIA_CBC); REGISTER(CRYPTO_AES_CTR); REGISTER(CRYPTO_AES_GCM_16); REGISTER(CRYPTO_AES_GMAC); REGISTER(CRYPTO_NULL_CBC); REGISTER(CRYPTO_MD5_HMAC); REGISTER(CRYPTO_MD5_HMAC_96); REGISTER(CRYPTO_SHA1_HMAC); REGISTER(CRYPTO_SHA1_HMAC_96); REGISTER(CRYPTO_SHA2_256_HMAC); REGISTER(CRYPTO_SHA2_384_HMAC); REGISTER(CRYPTO_SHA2_512_HMAC); REGISTER(CRYPTO_RIPEMD160_HMAC); REGISTER(CRYPTO_RIPEMD160_HMAC_96); REGISTER(CRYPTO_NULL_HMAC); REGISTER(CRYPTO_MD5_KPDK); REGISTER(CRYPTO_SHA1_KPDK); REGISTER(CRYPTO_MD5); REGISTER(CRYPTO_SHA1); REGISTER(CRYPTO_AES_XCBC_MAC_96); REGISTER(CRYPTO_AES_128_GMAC); REGISTER(CRYPTO_AES_192_GMAC); REGISTER(CRYPTO_AES_256_GMAC); REGISTER(CRYPTO_AES_CBC); REGISTER(CRYPTO_DEFLATE_COMP); REGISTER(CRYPTO_DEFLATE_COMP_NOGROW); REGISTER(CRYPTO_GZIP_COMP); #undef REGISTER } /* * Pseudo-device init routine for software crypto. */ void swcryptoattach(int num) { /* * swcrypto_attach() must be called after attached cpus, because * it calls softint_establish() through below call path. * swcr_init() => crypto_get_driverid() => crypto_init() * => crypto_init0() * If softint_establish() is called before attached cpus that ncpu == 0, * the softint handler is established to CPU#0 only. * * So, swcrypto_attach() must be called from not module_init_class() * but config_finalize() when it is built as builtin module. */ swcryptoattach_internal(); } void swcrypto_attach(device_t, device_t, void *); void swcrypto_attach(device_t parent, device_t self, void *opaque) { swcr_init(); if (!pmf_device_register(self, NULL, NULL)) aprint_error_dev(self, "couldn't establish power handler\n"); } int swcrypto_detach(device_t, int); int swcrypto_detach(device_t self, int flag) { pmf_device_deregister(self); if (swcr_id >= 0) crypto_unregister_all(swcr_id); return 0; } int swcrypto_match(device_t, cfdata_t, void *); int swcrypto_match(device_t parent, cfdata_t data, void *opaque) { return 1; } MODULE(MODULE_CLASS_DRIVER, swcrypto, "opencrypto,zlib,blowfish,des,cast128,camellia,skipjack"); CFDRIVER_DECL(swcrypto, DV_DULL, NULL); CFATTACH_DECL2_NEW(swcrypto, 0, swcrypto_match, swcrypto_attach, swcrypto_detach, NULL, NULL, NULL); static int swcryptoloc[] = { -1, -1 }; static struct cfdata swcrypto_cfdata[] = { { .cf_name = "swcrypto", .cf_atname = "swcrypto", .cf_unit = 0, .cf_fstate = 0, .cf_loc = swcryptoloc, .cf_flags = 0, .cf_pspec = NULL, }, { NULL, NULL, 0, 0, NULL, 0, NULL } }; /* * Internal attach routine. * Don't call before attached cpus. */ static int swcryptoattach_internal(void) { int error; error = config_cfdriver_attach(&swcrypto_cd); if (error) { return error; } error = config_cfattach_attach(swcrypto_cd.cd_name, &swcrypto_ca); if (error) { config_cfdriver_detach(&swcrypto_cd); aprint_error("%s: unable to register cfattach\n", swcrypto_cd.cd_name); return error; } error = config_cfdata_attach(swcrypto_cfdata, 1); if (error) { config_cfattach_detach(swcrypto_cd.cd_name, &swcrypto_ca); config_cfdriver_detach(&swcrypto_cd); aprint_error("%s: unable to register cfdata\n", swcrypto_cd.cd_name); return error; } (void)config_attach_pseudo(swcrypto_cfdata); return 0; } static int swcrypto_modcmd(modcmd_t cmd, void *arg) { int error = 0; switch (cmd) { case MODULE_CMD_INIT: #ifdef _MODULE error = swcryptoattach_internal(); #endif return error; case MODULE_CMD_FINI: #if 1 // XXX: Need to keep track if we are in use. return ENOTTY; #else error = config_cfdata_detach(swcrypto_cfdata); if (error) { return error; } config_cfattach_detach(swcrypto_cd.cd_name, &swcrypto_ca); config_cfdriver_detach(&swcrypto_cd); return 0; #endif default: return ENOTTY; } } @ 1.63 log @cryptosoft(4): Prune dead branches. Assert session id validity. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.62 2022/05/22 11:29:25 riastradh Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.62 2022/05/22 11:29:25 riastradh Exp $"); d78 1 a78 1 static int swcr_freesession(void *, u_int64_t); d1122 1 a1122 1 static int a1134 2 return 0; @ 1.62 log @cryptosoft(4): Rip out nonsense to quietly ignore sid=0. This is no longer necessary because crypto_freesession no longer calls into the driver for session ids that were never allocated in the first place. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.61 2021/04/06 03:38:04 knakahara Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.61 2021/04/06 03:38:04 knakahara Exp $"); a768 3 if (sid == NULL || cri == NULL) return EINVAL; d1128 3 a1130 3 if (sid > swcr_sesnum || swcr_sessions == NULL || swcr_sessions[sid] == NULL) return EINVAL; @ 1.61 log @Fix ATF failures, sorry. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.60 2021/04/05 01:24:50 knakahara Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.60 2021/04/05 01:24:50 knakahara Exp $"); a1134 4 /* Silently accept and return */ if (sid == 0) return 0; @ 1.60 log @refactor: reduce access to swcr_sessions[i] directly @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.59 2021/04/05 01:23:15 knakahara Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.59 2021/04/05 01:23:15 knakahara Exp $"); d715 1 a715 1 data = kmem_alloc(crd->crd_len, KM_NOSLEEP); d726 1 a726 1 kmem_free(data, crd->crd_len); d1118 1 a1118 1 free(swd, M_CRYPTO_DATA); @ 1.59 log @refactor: reduce changing swcr_sesnum @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.58 2021/04/05 01:22:22 knakahara Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.58 2021/04/05 01:22:22 knakahara Exp $"); d79 1 d762 1 d807 2 a808 3 swd = &swcr_sessions[i]; *sid = i; d812 2 a813 1 swcr_freesession(NULL, i); d815 2 a816 1 } d856 1 a856 1 swcr_freesession(NULL, i); d895 1 a895 1 swcr_freesession(NULL, i); d901 1 a901 1 swcr_freesession(NULL, i); d939 1 a939 1 swcr_freesession(NULL, i); d947 1 a947 1 swcr_freesession(NULL, i); d970 1 a970 1 swcr_freesession(NULL, i); d992 1 a992 1 swcr_freesession(NULL, i); d1016 1 a1016 1 swcr_freesession(NULL, i); d1024 3 d1030 2 a1031 5 /* * Free a session. */ static int swcr_freesession(void *arg, u_int64_t tid) d1033 1 a1033 1 struct swcr_data *swd; a1035 5 u_int32_t sid = ((u_int32_t) tid) & 0xffffffff; if (sid > swcr_sesnum || swcr_sessions == NULL || swcr_sessions[sid] == NULL) return EINVAL; d1037 2 a1038 3 /* Silently accept and return */ if (sid == 0) return 0; d1040 3 a1042 2 while ((swd = swcr_sessions[sid]) != NULL) { swcr_sessions[sid] = swd->sw_next; d1120 23 @ 1.58 log @use kmem_{z,}alloc() instead of malloc() @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.57 2020/07/04 18:07:31 riastradh Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.57 2020/07/04 18:07:31 riastradh Exp $"); d778 3 d783 1 a783 1 swcr_sesnum = CRYPTO_SW_SESSIONS; d785 1 a785 1 swcr_sesnum *= 2; d787 1 a787 1 swd = kmem_zalloc(swcr_sesnum * sizeof(struct swcr_data *), d789 1 a789 6 if (swd == NULL) { /* Reset session number */ if (swcr_sesnum == CRYPTO_SW_SESSIONS) swcr_sesnum = 0; else swcr_sesnum /= 2; d795 2 a796 2 memcpy(swd, swcr_sessions, (swcr_sesnum / 2) * sizeof(struct swcr_data *)); d798 1 a798 1 (swcr_sesnum / 2) * sizeof(struct swcr_data *)); d801 2 a802 1 swcr_sessions = swd; @ 1.57 log @Fix kmem_free size in recent malloc->kmem conversion. Should address this bracket report that has my name all over it: https://mail-index.netbsd.org/current-users/2020/07/04/msg039059.html @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.56 2020/06/29 23:34:48 riastradh Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.56 2020/06/29 23:34:48 riastradh Exp $"); d31 1 a31 1 #include d714 1 a714 1 data = malloc(crd->crd_len, M_CRYPTO_DATA, M_NOWAIT); d725 1 a725 1 free(data, M_CRYPTO_DATA); d784 2 a785 2 swd = malloc(swcr_sesnum * sizeof(struct swcr_data *), M_CRYPTO_DATA, M_NOWAIT); a794 2 memset(swd, 0, swcr_sesnum * sizeof(struct swcr_data *)); d799 2 a800 1 free(swcr_sessions, M_CRYPTO_DATA); d810 1 a810 1 *swd = malloc(sizeof **swd, M_CRYPTO_DATA, M_NOWAIT); a814 1 memset(*swd, 0, sizeof(struct swcr_data)); @ 1.57.4.1 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.61 2021/04/06 03:38:04 knakahara Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.61 2021/04/06 03:38:04 knakahara Exp $"); d31 1 a31 1 #include a78 1 static void swcr_freesession_internal(struct swcr_data *); a760 1 struct swcr_data *first, *tmp; a777 3 u_int32_t newnum; struct swcr_data **newsessions; d780 1 a780 1 newnum = CRYPTO_SW_SESSIONS; d782 1 a782 1 newnum = swcr_sesnum *= 2; d784 8 a791 3 newsessions = kmem_zalloc(newnum * sizeof(struct swcr_data *), KM_NOSLEEP); if (newsessions == NULL) { d795 2 d799 3 a801 4 memcpy(newsessions, swcr_sessions, swcr_sesnum * sizeof(struct swcr_data *)); kmem_free(swcr_sessions, swcr_sesnum * sizeof(struct swcr_data *)); d804 1 a804 2 swcr_sesnum = newnum; swcr_sessions = newsessions; d807 3 a809 2 first = NULL; swd = &tmp; d811 1 a811 1 *swd = kmem_zalloc(sizeof **swd, KM_NOSLEEP); d813 1 a813 2 if (first != NULL) swcr_freesession_internal(first); d815 2 a816 2 } else if (first == NULL) first = *swd; d856 1 a856 1 swcr_freesession_internal(first); d895 1 a895 1 swcr_freesession_internal(first); d901 1 a901 1 swcr_freesession_internal(first); d939 1 a939 1 swcr_freesession_internal(first); d947 1 a947 1 swcr_freesession_internal(first); d970 1 a970 1 swcr_freesession_internal(first); d992 1 a992 1 swcr_freesession_internal(first); d1016 1 a1016 1 swcr_freesession_internal(first); a1023 3 swcr_sessions[i] = first; *sid = i; d1027 5 a1031 2 static void swcr_freesession_internal(struct swcr_data *arg) d1033 1 a1033 1 struct swcr_data *swd, *swd0; d1036 5 d1042 3 a1044 2 if (arg == NULL) return; d1046 2 a1047 3 swd0 = arg; while ((swd = swd0) != NULL) { swd0 = swd->sw_next; d1123 1 a1123 1 kmem_free(swd, sizeof(*swd)); a1124 23 } /* * Free a session. */ static int swcr_freesession(void *arg, u_int64_t tid) { struct swcr_data *swd; u_int32_t sid = ((u_int32_t) tid) & 0xffffffff; if (sid > swcr_sesnum || swcr_sessions == NULL || swcr_sessions[sid] == NULL) return EINVAL; /* Silently accept and return */ if (sid == 0) return 0; swd = swcr_sessions[sid]; swcr_sessions[sid] = NULL; swcr_freesession_internal(swd); @ 1.56 log @opencrypto: Switch from legacy rijndael API to new aes API. While here, apply various rijndael->aes renames, reduce the size of aesxcbc_ctx by 480 bytes, and convert some malloc->kmem. Leave in the symbol enc_xform_rijndael128 for now, though, so this doesn't break any kernel ABI. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.55 2020/06/14 23:23:55 riastradh Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.55 2020/06/14 23:23:55 riastradh Exp $"); d1099 1 a1099 1 kmem_free(swd->sw_octx, axf->ctxsize); @ 1.55 log @swcrypto(4): Simplify iv generation logic with cprng_fast. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.54 2019/10/12 00:49:30 christos Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.54 2019/10/12 00:49:30 christos Exp $"); d834 2 a835 2 case CRYPTO_RIJNDAEL128_CBC: txf = &swcr_enc_xform_rijndael128; d893 1 a893 2 (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT); d899 1 a899 2 (*swd)->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT); d937 1 a937 2 (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT); d944 2 a945 2 (*swd)->sw_octx = malloc(cri->cri_klen / 8, M_CRYPTO_DATA, M_NOWAIT); d968 1 a968 2 (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT); d990 1 a990 2 (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT); d1055 1 a1055 1 case CRYPTO_RIJNDAEL128_CBC: d1081 1 a1081 1 free(swd->sw_ictx, M_CRYPTO_DATA); d1085 1 a1085 1 free(swd->sw_octx, M_CRYPTO_DATA); d1095 1 a1095 1 free(swd->sw_ictx, M_CRYPTO_DATA); d1099 1 a1099 1 free(swd->sw_octx, M_CRYPTO_DATA); d1113 1 a1113 1 free(swd->sw_ictx, M_CRYPTO_DATA); d1191 1 a1191 1 case CRYPTO_RIJNDAEL128_CBC: d1292 1 a1292 1 REGISTER(CRYPTO_RIJNDAEL128_CBC); @ 1.54 log @add (void *) intermediate casts to elide gcc function cast warnings. This is the simplest solution; choices: - add pragmas, complex and ugly (need to be gcc-specific) - add -Wno to COPTS. Needs to be done in many makefiles because of rump - add intermediate functions: slows down things @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.53 2019/07/11 23:27:24 christos Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.53 2019/07/11 23:27:24 christos Exp $"); d115 1 a115 19 /* Get random IV */ for (i = 0; i + sizeof (u_int32_t) <= EALG_MAX_BLOCK_LEN; i += sizeof (u_int32_t)) { u_int32_t temp = cprng_fast32(); memcpy(iv + i, &temp, sizeof(u_int32_t)); } /* * What if the block size is not a multiple * of sizeof (u_int32_t), which is the size of * what arc4random() returns ? */ if (EALG_MAX_BLOCK_LEN % sizeof (u_int32_t) != 0) { u_int32_t temp = cprng_fast32(); bcopy (&temp, iv + i, EALG_MAX_BLOCK_LEN - i); } @ 1.53 log @Disable unloading until we keep track of references @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.52 2017/06/23 11:41:58 knakahara Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.52 2017/06/23 11:41:58 knakahara Exp $"); d503 1 a503 1 (int (*)(void*, void *, unsigned int)) axf->Update, d511 1 a511 1 (int (*)(void *, void *, unsigned int)) axf->Update, @ 1.52 log @fix cryptosoft.c:r1.51 mistake. swcrypto_attach() must not be called from module_init_class(). swcrypto_attach() will call softint_establish(), it must be called after cpus attached. module_init_class() is too early to call softint_establish(). @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.51 2017/06/01 08:49:35 knakahara Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.51 2017/06/01 08:49:35 knakahara Exp $"); d1450 4 d1463 1 @ 1.52.6.1 log @Mostly merge changes from HEAD upto 20200411 @ text @d1 1 a1 1 /* $NetBSD$ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD$"); d503 1 a503 1 (int (*)(void*, void *, unsigned int))(void *)axf->Update, d511 1 a511 1 (int (*)(void *, void *, unsigned int))(void *)axf->Update, a1449 4 #if 1 // XXX: Need to keep track if we are in use. return ENOTTY; #else a1458 1 #endif @ 1.51 log @swcrypto0 was initialized twice. Fix like pseudo network interfaces. ok by pgoyette@@n.o. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.50 2017/05/17 06:33:04 knakahara Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.50 2017/05/17 06:33:04 knakahara Exp $"); d80 2 d1331 9 a1339 2 * Nothing to do here, initialization is handled by the * module initialization code in swcrypto_attach() below). d1341 1 d1399 4 d1404 1 a1404 1 swcrypto_modcmd(modcmd_t cmd, void *arg) d1408 13 a1420 6 switch (cmd) { case MODULE_CMD_INIT: error = config_cfdriver_attach(&swcrypto_cd); if (error) { return error; } d1422 3 a1424 1 error = config_cfattach_attach(swcrypto_cd.cd_name, d1426 3 a1428 4 if (error) { config_cfdriver_detach(&swcrypto_cd); aprint_error("%s: unable to register cfattach\n", swcrypto_cd.cd_name); d1430 2 a1431 2 return error; } d1433 1 a1433 7 error = config_cfdata_attach(swcrypto_cfdata, 1); if (error) { config_cfattach_detach(swcrypto_cd.cd_name, &swcrypto_ca); config_cfdriver_detach(&swcrypto_cd); aprint_error("%s: unable to register cfdata\n", swcrypto_cd.cd_name); d1435 2 a1436 2 return error; } d1438 4 a1441 1 (void)config_attach_pseudo(swcrypto_cfdata); d1443 6 a1448 1 return 0; @ 1.51.2.1 log @Pull up following revision(s) (requested by knakahara in ticket #97): sys/opencrypto/crypto.c: 1.87-1.91 sys/opencrypto/cryptodev.c: 1.93-1.95 sys/opencrypto/cryptodev.h: 1.37 sys/opencrypto/cryptosoft.c: 1.52 sys/rump/dev/lib/libopencrypto/opencrypto_component.c: 1.5 sanitize count used for kmem_alloc size. Hmm, who uses CIOCNGSESSION, CIOCNFSESSION, CIOCNCRYPTM or CIOCNFKEYM? -- sanitize in CIOCNCRYPTM and initialize comp_alg in CIOCNGSESSION -- must release cap->cc_lock before calling cap->cc_newsession() because of spinlock. -- refactor crypto_newsession() like FreeBSD. -- support multiple encryption drivers (port from FreeBSD). -- Divide crp_devflags from crp_flags to write exclusively. CRYPTO_F_DQRETQ(new name is CRYPTODEV_F_RET) is used by cryptodev.c only. It should be divided to other member. -- Reduce crypto_ret_q_mtx lock regions. crypto.c does not access the members of crp when the crp is in crp_q or crp_ret_q. Furthermore, crp_q and crp_ret_q are protected by each mutex, so the members of crp is not shared. That means crp_flags is not required mutex in crypto.c. -- fix cryptosoft.c:r1.51 mistake. swcrypto_attach() must not be called from module_init_class(). swcrypto_attach() will call softint_establish(), it must be called after cpus attached. module_init_class() is too early to call softint_establish(). -- simplify mutex_enter/exit(crypto_q_mtx), and fix missing exit. -- reduce rump waring message. pointed out by ozaki-r@@n.o, thanks. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.51 2017/06/01 08:49:35 knakahara Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.51 2017/06/01 08:49:35 knakahara Exp $"); a79 2 static int swcryptoattach_internal(void); d1329 2 a1330 9 * swcrypto_attach() must be called after attached cpus, because * it calls softint_establish() through below call path. * swcr_init() => crypto_get_driverid() => crypto_init() * => crypto_init0() * If softint_establish() is called before attached cpus that ncpu == 0, * the softint handler is established to CPU#0 only. * * So, swcrypto_attach() must be called from not module_init_class() * but config_finalize() when it is built as builtin module. a1331 1 swcryptoattach_internal(); a1388 4 /* * Internal attach routine. * Don't call before attached cpus. */ d1390 1 a1390 1 swcryptoattach_internal(void) d1394 6 a1399 10 error = config_cfdriver_attach(&swcrypto_cd); if (error) { return error; } error = config_cfattach_attach(swcrypto_cd.cd_name, &swcrypto_ca); if (error) { config_cfdriver_detach(&swcrypto_cd); aprint_error("%s: unable to register cfattach\n", swcrypto_cd.cd_name); d1401 1 a1401 6 return error; } error = config_cfdata_attach(swcrypto_cfdata, 1); if (error) { config_cfattach_detach(swcrypto_cd.cd_name, d1403 4 a1406 3 config_cfdriver_detach(&swcrypto_cd); aprint_error("%s: unable to register cfdata\n", swcrypto_cd.cd_name); d1408 2 a1409 2 return error; } d1411 7 a1417 1 (void)config_attach_pseudo(swcrypto_cfdata); d1419 2 a1420 2 return 0; } d1422 1 a1422 4 static int swcrypto_modcmd(modcmd_t cmd, void *arg) { int error = 0; d1424 1 a1424 6 switch (cmd) { case MODULE_CMD_INIT: #ifdef _MODULE error = swcryptoattach_internal(); #endif return error; @ 1.50 log @opencrypto: cleanup debug messages. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.49 2017/04/18 17:05:05 maya Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.49 2017/04/18 17:05:05 maya Exp $"); d1328 4 a1331 2 swcr_init(); @ 1.49 log @Remove duplicate assignment. We assign the same value unconditionally just before. from clang static analyzer XXX surrounding code seems fishy @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.48 2017/04/13 01:24:34 ozaki-r Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.48 2017/04/13 01:24:34 ozaki-r Exp $"); d1253 1 a1253 1 DPRINTF(("swcr_process: compdec for %d\n", sw->sw_alg)); d1267 1 a1267 1 DPRINTF(("request %p done\n", crp)); @ 1.49.2.1 log @At suggestion of chuq@@, modify config_attach_pseudo() to return with a reference held on the device. Adapt callers to expect the reference to exist, and to ensure that the reference is released. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.49 2017/04/18 17:05:05 maya Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.49 2017/04/18 17:05:05 maya Exp $"); a1390 1 device_t dev; d1420 1 a1420 2 dev = config_attach_pseudo(swcrypto_cfdata); device_release(dev); @ 1.49.2.2 log @Resolve conflicts from previous merge (all resulting from $NetBSD keywork expansion) @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.50 2017/05/17 06:33:04 knakahara Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.50 2017/05/17 06:33:04 knakahara Exp $"); d1253 1 a1253 1 DPRINTF("compdec for %d\n", sw->sw_alg); d1267 1 a1267 1 DPRINTF("request %p done\n", crp); @ 1.48 log @Fix usage of MD5Final/SHA1Final Passing NULL as the digest parameter is wrong. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.47 2015/08/20 14:40:19 christos Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.47 2015/08/20 14:40:19 christos Exp $"); a761 1 adj = result - crd->crd_len; @ 1.47 log @include "ioconf.h" to get the 'void attach(int count);' prototype. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.46 2014/07/02 18:58:42 riastradh Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.46 2014/07/02 18:58:42 riastradh Exp $"); d951 3 a953 1 case CRYPTO_SHA1_KPDK: d976 1 a976 1 axf->Final(NULL, (*swd)->sw_ictx); d979 1 @ 1.47.2.1 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.49 2017/04/18 17:05:05 maya Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.49 2017/04/18 17:05:05 maya Exp $"); d762 1 d951 1 a951 3 case CRYPTO_SHA1_KPDK: { unsigned char digest[SHA1_DIGEST_LENGTH]; CTASSERT(SHA1_DIGEST_LENGTH >= MD5_DIGEST_LENGTH); d974 1 a974 1 axf->Final(digest, (*swd)->sw_ictx); a976 1 } @ 1.47.4.1 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.49 2017/04/18 17:05:05 maya Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.49 2017/04/18 17:05:05 maya Exp $"); d762 1 d951 1 a951 3 case CRYPTO_SHA1_KPDK: { unsigned char digest[SHA1_DIGEST_LENGTH]; CTASSERT(SHA1_DIGEST_LENGTH >= MD5_DIGEST_LENGTH); d974 1 a974 1 axf->Final(digest, (*swd)->sw_ictx); a976 1 } @ 1.46 log @If we register with pmf on attach, deregister on detach. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.45 2014/06/21 17:34:30 christos Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.45 2014/06/21 17:34:30 christos Exp $"); d49 2 a1321 1 void swcryptoattach(int); @ 1.46.4.1 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.47 2015/08/20 14:40:19 christos Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.47 2015/08/20 14:40:19 christos Exp $"); a48 2 #include "ioconf.h" d1320 1 @ 1.46.4.2 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.46.4.1 2015/09/22 12:06:12 skrll Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.46.4.1 2015/09/22 12:06:12 skrll Exp $"); a79 2 static int swcryptoattach_internal(void); d762 1 d951 1 a951 3 case CRYPTO_SHA1_KPDK: { unsigned char digest[SHA1_DIGEST_LENGTH]; CTASSERT(SHA1_DIGEST_LENGTH >= MD5_DIGEST_LENGTH); d974 1 a974 1 axf->Final(digest, (*swd)->sw_ictx); a976 1 } d1251 1 a1251 1 DPRINTF("compdec for %d\n", sw->sw_alg); d1265 1 a1265 1 DPRINTF("request %p done\n", crp); d1326 2 a1327 12 /* * swcrypto_attach() must be called after attached cpus, because * it calls softint_establish() through below call path. * swcr_init() => crypto_get_driverid() => crypto_init() * => crypto_init0() * If softint_establish() is called before attached cpus that ncpu == 0, * the softint handler is established to CPU#0 only. * * So, swcrypto_attach() must be called from not module_init_class() * but config_finalize() when it is built as builtin module. */ swcryptoattach_internal(); a1384 4 /* * Internal attach routine. * Don't call before attached cpus. */ d1386 1 a1386 1 swcryptoattach_internal(void) d1390 6 a1395 13 error = config_cfdriver_attach(&swcrypto_cd); if (error) { return error; } error = config_cfattach_attach(swcrypto_cd.cd_name, &swcrypto_ca); if (error) { config_cfdriver_detach(&swcrypto_cd); aprint_error("%s: unable to register cfattach\n", swcrypto_cd.cd_name); return error; } d1397 1 a1397 3 error = config_cfdata_attach(swcrypto_cfdata, 1); if (error) { config_cfattach_detach(swcrypto_cd.cd_name, d1399 4 a1402 3 config_cfdriver_detach(&swcrypto_cd); aprint_error("%s: unable to register cfdata\n", swcrypto_cd.cd_name); d1404 2 a1405 2 return error; } d1407 7 a1413 1 (void)config_attach_pseudo(swcrypto_cfdata); d1415 2 a1416 2 return 0; } d1418 1 a1418 4 static int swcrypto_modcmd(modcmd_t cmd, void *arg) { int error = 0; d1420 1 a1420 6 switch (cmd) { case MODULE_CMD_INIT: #ifdef _MODULE error = swcryptoattach_internal(); #endif return error; @ 1.45 log @register with pmf. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.44 2014/01/01 16:06:01 pgoyette Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.44 2014/01/01 16:06:01 pgoyette Exp $"); d1346 1 @ 1.44 log @Modularize the opencrypto components and link to the build @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.43 2013/09/12 13:12:35 martin Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.43 2013/09/12 13:12:35 martin Exp $"); d1336 3 @ 1.44.2.1 log @Rebase. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.46 2014/07/02 18:58:42 riastradh Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.46 2014/07/02 18:58:42 riastradh Exp $"); a1335 3 if (!pmf_device_register(self, NULL, NULL)) aprint_error_dev(self, "couldn't establish power handler\n"); a1342 1 pmf_device_deregister(self); @ 1.43 log @Remove unused variable @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.42 2013/06/24 04:21:20 riastradh Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.42 2013/06/24 04:21:20 riastradh Exp $"); d36 2 d39 1 d41 2 d1328 102 @ 1.42 log @Replace consttime_bcmp/explicit_bzero by consttime_memequal/explicit_memset. consttime_memequal is the same as the old consttime_bcmp. explicit_memset is to memset as explicit_bzero was to bcmp. Passes amd64 release and i386/ALL, but I'm sure I missed some spots, so please let me know. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.41 2013/02/02 21:38:24 christos Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.41 2013/02/02 21:38:24 christos Exp $"); a1047 1 const struct swcr_comp_algo *cxf; a1131 1 cxf = swd->sw_cxf; @ 1.42.2.1 log @sync with head @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.42 2013/06/24 04:21:20 riastradh Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.42 2013/06/24 04:21:20 riastradh Exp $"); a35 2 #include #include a36 1 #ifdef _KERNEL_OPT a37 2 #endif d1048 1 d1133 1 a1324 102 void swcrypto_attach(device_t, device_t, void *); void swcrypto_attach(device_t parent, device_t self, void *opaque) { swcr_init(); } int swcrypto_detach(device_t, int); int swcrypto_detach(device_t self, int flag) { if (swcr_id >= 0) crypto_unregister_all(swcr_id); return 0; } int swcrypto_match(device_t, cfdata_t, void *); int swcrypto_match(device_t parent, cfdata_t data, void *opaque) { return 1; } MODULE(MODULE_CLASS_DRIVER, swcrypto, "opencrypto,zlib,blowfish,des,cast128,camellia,skipjack"); CFDRIVER_DECL(swcrypto, DV_DULL, NULL); CFATTACH_DECL2_NEW(swcrypto, 0, swcrypto_match, swcrypto_attach, swcrypto_detach, NULL, NULL, NULL); static int swcryptoloc[] = { -1, -1 }; static struct cfdata swcrypto_cfdata[] = { { .cf_name = "swcrypto", .cf_atname = "swcrypto", .cf_unit = 0, .cf_fstate = 0, .cf_loc = swcryptoloc, .cf_flags = 0, .cf_pspec = NULL, }, { NULL, NULL, 0, 0, NULL, 0, NULL } }; static int swcrypto_modcmd(modcmd_t cmd, void *arg) { int error; switch (cmd) { case MODULE_CMD_INIT: error = config_cfdriver_attach(&swcrypto_cd); if (error) { return error; } error = config_cfattach_attach(swcrypto_cd.cd_name, &swcrypto_ca); if (error) { config_cfdriver_detach(&swcrypto_cd); aprint_error("%s: unable to register cfattach\n", swcrypto_cd.cd_name); return error; } error = config_cfdata_attach(swcrypto_cfdata, 1); if (error) { config_cfattach_detach(swcrypto_cd.cd_name, &swcrypto_ca); config_cfdriver_detach(&swcrypto_cd); aprint_error("%s: unable to register cfdata\n", swcrypto_cd.cd_name); return error; } (void)config_attach_pseudo(swcrypto_cfdata); return 0; case MODULE_CMD_FINI: error = config_cfdata_detach(swcrypto_cfdata); if (error) { return error; } config_cfattach_detach(swcrypto_cd.cd_name, &swcrypto_ca); config_cfdriver_detach(&swcrypto_cd); return 0; default: return ENOTTY; } } @ 1.41 log @fix compilation @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.40 2012/08/30 12:16:49 drochner Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.40 2012/08/30 12:16:49 drochner Exp $"); d1093 1 a1093 1 explicit_bzero(swd->sw_ictx, axf->ctxsize); d1097 1 a1097 1 explicit_bzero(swd->sw_octx, axf->ctxsize); d1107 1 a1107 1 explicit_bzero(swd->sw_ictx, axf->ctxsize); d1111 1 a1111 1 explicit_bzero(swd->sw_octx, swd->sw_klen); d1125 1 a1125 1 explicit_bzero(swd->sw_ictx, axf->ctxsize); @ 1.40 log @Add "consttime_bcmp" and "explicit_bzero" functions for both kernel abd userland, as proposed on tech-security, with explicit_bzero using a volatile function pointer as suggested by Alan Barrett. Both do what the name says. For userland, both are prefixed by "__" to keep them out of the user namespace. Change some memset/memcmp uses to the new functions where it makes sense -- these are just some examples, more to come. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.39 2011/11/28 08:05:06 tls Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.39 2011/11/28 08:05:06 tls Exp $"); d35 1 @ 1.40.2.1 log @resync with head @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.40 2012/08/30 12:16:49 drochner Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.40 2012/08/30 12:16:49 drochner Exp $"); a34 1 #include @ 1.40.2.2 log @Rebase to HEAD as of a few days ago. @ text @d1 1 a1 1 /* $NetBSD$ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD$"); a35 2 #include #include a36 1 #ifdef _KERNEL_OPT a37 2 #endif d1048 1 d1093 1 a1093 1 explicit_memset(swd->sw_ictx, 0, axf->ctxsize); d1097 1 a1097 1 explicit_memset(swd->sw_octx, 0, axf->ctxsize); d1107 1 a1107 1 explicit_memset(swd->sw_ictx, 0, axf->ctxsize); d1111 1 a1111 1 explicit_memset(swd->sw_octx, 0, swd->sw_klen); d1125 1 a1125 1 explicit_memset(swd->sw_ictx, 0, axf->ctxsize); d1133 1 a1324 106 void swcrypto_attach(device_t, device_t, void *); void swcrypto_attach(device_t parent, device_t self, void *opaque) { swcr_init(); if (!pmf_device_register(self, NULL, NULL)) aprint_error_dev(self, "couldn't establish power handler\n"); } int swcrypto_detach(device_t, int); int swcrypto_detach(device_t self, int flag) { pmf_device_deregister(self); if (swcr_id >= 0) crypto_unregister_all(swcr_id); return 0; } int swcrypto_match(device_t, cfdata_t, void *); int swcrypto_match(device_t parent, cfdata_t data, void *opaque) { return 1; } MODULE(MODULE_CLASS_DRIVER, swcrypto, "opencrypto,zlib,blowfish,des,cast128,camellia,skipjack"); CFDRIVER_DECL(swcrypto, DV_DULL, NULL); CFATTACH_DECL2_NEW(swcrypto, 0, swcrypto_match, swcrypto_attach, swcrypto_detach, NULL, NULL, NULL); static int swcryptoloc[] = { -1, -1 }; static struct cfdata swcrypto_cfdata[] = { { .cf_name = "swcrypto", .cf_atname = "swcrypto", .cf_unit = 0, .cf_fstate = 0, .cf_loc = swcryptoloc, .cf_flags = 0, .cf_pspec = NULL, }, { NULL, NULL, 0, 0, NULL, 0, NULL } }; static int swcrypto_modcmd(modcmd_t cmd, void *arg) { int error; switch (cmd) { case MODULE_CMD_INIT: error = config_cfdriver_attach(&swcrypto_cd); if (error) { return error; } error = config_cfattach_attach(swcrypto_cd.cd_name, &swcrypto_ca); if (error) { config_cfdriver_detach(&swcrypto_cd); aprint_error("%s: unable to register cfattach\n", swcrypto_cd.cd_name); return error; } error = config_cfdata_attach(swcrypto_cfdata, 1); if (error) { config_cfattach_detach(swcrypto_cd.cd_name, &swcrypto_ca); config_cfdriver_detach(&swcrypto_cd); aprint_error("%s: unable to register cfdata\n", swcrypto_cd.cd_name); return error; } (void)config_attach_pseudo(swcrypto_cfdata); return 0; case MODULE_CMD_FINI: error = config_cfdata_detach(swcrypto_cfdata); if (error) { return error; } config_cfattach_detach(swcrypto_cd.cd_name, &swcrypto_ca); config_cfdriver_detach(&swcrypto_cd); return 0; default: return ENOTTY; } } @ 1.40.2.3 log @update from HEAD @ text @a48 2 #include "ioconf.h" a77 2 static int swcryptoattach_internal(void); d760 1 d949 1 a949 3 case CRYPTO_SHA1_KPDK: { unsigned char digest[SHA1_DIGEST_LENGTH]; CTASSERT(SHA1_DIGEST_LENGTH >= MD5_DIGEST_LENGTH); d972 1 a972 1 axf->Final(digest, (*swd)->sw_ictx); a974 1 } d1249 1 a1249 1 DPRINTF("compdec for %d\n", sw->sw_alg); d1263 1 a1263 1 DPRINTF("request %p done\n", crp); d1320 1 d1325 2 a1326 12 /* * swcrypto_attach() must be called after attached cpus, because * it calls softint_establish() through below call path. * swcr_init() => crypto_get_driverid() => crypto_init() * => crypto_init0() * If softint_establish() is called before attached cpus that ncpu == 0, * the softint handler is established to CPU#0 only. * * So, swcrypto_attach() must be called from not module_init_class() * but config_finalize() when it is built as builtin module. */ swcryptoattach_internal(); a1383 4 /* * Internal attach routine. * Don't call before attached cpus. */ d1385 1 a1385 1 swcryptoattach_internal(void) d1389 6 a1394 10 error = config_cfdriver_attach(&swcrypto_cd); if (error) { return error; } error = config_cfattach_attach(swcrypto_cd.cd_name, &swcrypto_ca); if (error) { config_cfdriver_detach(&swcrypto_cd); aprint_error("%s: unable to register cfattach\n", swcrypto_cd.cd_name); d1396 1 a1396 6 return error; } error = config_cfdata_attach(swcrypto_cfdata, 1); if (error) { config_cfattach_detach(swcrypto_cd.cd_name, d1398 4 a1401 3 config_cfdriver_detach(&swcrypto_cd); aprint_error("%s: unable to register cfdata\n", swcrypto_cd.cd_name); d1403 2 a1404 2 return error; } d1406 7 a1412 1 (void)config_attach_pseudo(swcrypto_cfdata); d1414 2 a1415 2 return 0; } d1417 1 a1417 4 static int swcrypto_modcmd(modcmd_t cmd, void *arg) { int error = 0; d1419 1 a1419 6 switch (cmd) { case MODULE_CMD_INIT: #ifdef _MODULE error = swcryptoattach_internal(); #endif return error; @ 1.39 log @Remove arc4random() and arc4randbytes() from the kernel API. Replace arc4random() hacks in rump with stubs that call the host arc4random() to get numbers that are hopefully actually random (arc4random() keyed with stack junk is not). This should fix some of the currently failing anita tests -- we should no longer generate duplicate "random" MAC addresses in the test environment. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.38 2011/06/07 15:57:51 drochner Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.38 2011/06/07 15:57:51 drochner Exp $"); d1092 1 a1092 1 memset(swd->sw_ictx, 0, axf->ctxsize); d1096 1 a1096 1 memset(swd->sw_octx, 0, axf->ctxsize); d1106 1 a1106 1 memset(swd->sw_ictx, 0, axf->ctxsize); d1110 1 a1110 1 memset(swd->sw_octx, 0, swd->sw_klen); d1123 2 a1124 1 if (swd->sw_ictx) d1126 1 @ 1.38 log @use a simple counter as IV for AES-GMAC as suggested in RFC4543 @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.37 2011/05/26 21:50:03 drochner Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.37 2011/05/26 21:50:03 drochner Exp $"); d109 1 a109 1 u_int32_t temp = arc4random(); d119 1 a119 1 u_int32_t temp = arc4random(); d631 1 a631 1 arc4randbytes(iv, ivlen); @ 1.38.2.1 log @sync with head @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.38 2011/06/07 15:57:51 drochner Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.38 2011/06/07 15:57:51 drochner Exp $"); d109 1 a109 1 u_int32_t temp = cprng_fast32(); d119 1 a119 1 u_int32_t temp = cprng_fast32(); d631 1 a631 1 cprng_fast(iv, ivlen); @ 1.38.2.2 log @sync with head @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.38.2.1 2012/04/17 00:08:48 yamt Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.38.2.1 2012/04/17 00:08:48 yamt Exp $"); d1092 1 a1092 1 explicit_bzero(swd->sw_ictx, axf->ctxsize); d1096 1 a1096 1 explicit_bzero(swd->sw_octx, axf->ctxsize); d1106 1 a1106 1 explicit_bzero(swd->sw_ictx, axf->ctxsize); d1110 1 a1110 1 explicit_bzero(swd->sw_octx, swd->sw_klen); d1123 1 a1123 2 if (swd->sw_ictx) { explicit_bzero(swd->sw_ictx, axf->ctxsize); a1124 1 } @ 1.38.2.3 log @sync with head. for a reference, the tree before this commit was tagged as yamt-pagecache-tag8. this commit was splitted into small chunks to avoid a limitation of cvs. ("Protocol error: too many arguments") @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.38.2.2 2012/10/30 17:22:52 yamt Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.38.2.2 2012/10/30 17:22:52 yamt Exp $"); a34 3 #include #include #include a35 1 #ifdef _KERNEL_OPT a36 2 #endif d1047 1 d1092 1 a1092 1 explicit_memset(swd->sw_ictx, 0, axf->ctxsize); d1096 1 a1096 1 explicit_memset(swd->sw_octx, 0, axf->ctxsize); d1106 1 a1106 1 explicit_memset(swd->sw_ictx, 0, axf->ctxsize); d1110 1 a1110 1 explicit_memset(swd->sw_octx, 0, swd->sw_klen); d1124 1 a1124 1 explicit_memset(swd->sw_ictx, 0, axf->ctxsize); d1132 1 a1323 102 void swcrypto_attach(device_t, device_t, void *); void swcrypto_attach(device_t parent, device_t self, void *opaque) { swcr_init(); } int swcrypto_detach(device_t, int); int swcrypto_detach(device_t self, int flag) { if (swcr_id >= 0) crypto_unregister_all(swcr_id); return 0; } int swcrypto_match(device_t, cfdata_t, void *); int swcrypto_match(device_t parent, cfdata_t data, void *opaque) { return 1; } MODULE(MODULE_CLASS_DRIVER, swcrypto, "opencrypto,zlib,blowfish,des,cast128,camellia,skipjack"); CFDRIVER_DECL(swcrypto, DV_DULL, NULL); CFATTACH_DECL2_NEW(swcrypto, 0, swcrypto_match, swcrypto_attach, swcrypto_detach, NULL, NULL, NULL); static int swcryptoloc[] = { -1, -1 }; static struct cfdata swcrypto_cfdata[] = { { .cf_name = "swcrypto", .cf_atname = "swcrypto", .cf_unit = 0, .cf_fstate = 0, .cf_loc = swcryptoloc, .cf_flags = 0, .cf_pspec = NULL, }, { NULL, NULL, 0, 0, NULL, 0, NULL } }; static int swcrypto_modcmd(modcmd_t cmd, void *arg) { int error; switch (cmd) { case MODULE_CMD_INIT: error = config_cfdriver_attach(&swcrypto_cd); if (error) { return error; } error = config_cfattach_attach(swcrypto_cd.cd_name, &swcrypto_ca); if (error) { config_cfdriver_detach(&swcrypto_cd); aprint_error("%s: unable to register cfattach\n", swcrypto_cd.cd_name); return error; } error = config_cfdata_attach(swcrypto_cfdata, 1); if (error) { config_cfattach_detach(swcrypto_cd.cd_name, &swcrypto_ca); config_cfdriver_detach(&swcrypto_cd); aprint_error("%s: unable to register cfdata\n", swcrypto_cd.cd_name); return error; } (void)config_attach_pseudo(swcrypto_cfdata); return 0; case MODULE_CMD_FINI: error = config_cfdata_detach(swcrypto_cfdata); if (error) { return error; } config_cfattach_detach(swcrypto_cd.cd_name, &swcrypto_ca); config_cfdriver_detach(&swcrypto_cd); return 0; default: return ENOTTY; } } @ 1.37 log @pull in AES-GCM/GMAC support from OpenBSD This is still somewhat experimental. Tested between 2 similar boxes so far. There is much potential for performance improvement. For now, I've changed the gmac code to accept any data alignment, as the "char *" pointer suggests. As the code is practically used, 32-bit alignment can be assumed, at the cost of data copies. I don't know whether bytewise access or copies are worse performance-wise. For efficient implementations using SSE2 instructions on x86, even stricter alignment requirements might arise. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.36 2011/05/24 19:10:10 drochner Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.36 2011/05/24 19:10:10 drochner Exp $"); d855 3 a870 5 case CRYPTO_AES_GMAC: txf = &swcr_enc_xform_aes_gmac; (*swd)->sw_exf = txf; break; d1071 1 a1078 3 case CRYPTO_AES_GMAC: break; @ 1.37.2.1 log @Catchup with rmind-uvmplock merge. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.38 2011/06/07 15:57:51 drochner Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.38 2011/06/07 15:57:51 drochner Exp $"); a854 3 case CRYPTO_AES_GMAC: txf = &swcr_enc_xform_aes_gmac; goto enccommon; d868 5 a1072 1 case CRYPTO_AES_GMAC: d1080 3 @ 1.36 log @copy AES-XCBC-MAC support from KAME IPSEC to FAST_IPSEC For this to fit, an API change in cryptosoft was adopted from OpenBSD (addition of a "Setkey" method to hashes) which was done for GCM/GMAC support there, so it might be useful in the future anyway. tested against KAME IPSEC AFAICT, FAST_IPSEC now supports as much as KAME. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.35 2011/05/24 18:59:22 drochner Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.35 2011/05/24 18:59:22 drochner Exp $"); d51 1 d67 1 d567 137 d852 3 d868 5 d992 10 d1072 1 d1080 3 d1122 3 d1236 8 d1286 2 d1304 3 @ 1.35 log @move the "context size" struct member (which is a pure software implementation thing) from the abstract xform descriptor to the cryptosoft implementation part -- for sanity, and now clients of opencrypto don't depend on headers of cipher implementations anymore @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.34 2011/05/24 18:52:51 drochner Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.34 2011/05/24 18:52:51 drochner Exp $"); d50 1 d540 1 d843 14 d960 1 d1066 1 d1129 1 @ 1.34 log @Change the way the IV is generated for AES-CTR: use a simple counter instead of arc4random(). AES-CTR is sensitive against IV recurrence (with the same key / nonce), and a random number doesn't give that guarantee. This needs a little API change in cryptosoft -- I've suggested it to Open/FreeBSD, might change it depending on feedback. Thanks to Steven Bellovin for hints. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.33 2011/05/23 13:51:10 drochner Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.33 2011/05/23 13:51:10 drochner Exp $"); d482 1 a482 1 memcpy(&ctx, sw->sw_ictx, axf->auth_hash->ctxsize); d522 1 a522 1 memcpy(&ctx, sw->sw_octx, axf->auth_hash->ctxsize); d755 1 a755 1 (*swd)->sw_ictx = malloc(axf->auth_hash->ctxsize, d762 1 a762 1 (*swd)->sw_octx = malloc(axf->auth_hash->ctxsize, d799 1 a799 1 (*swd)->sw_ictx = malloc(axf->auth_hash->ctxsize, d830 1 a830 1 (*swd)->sw_ictx = malloc(axf->auth_hash->ctxsize, d919 1 a919 1 memset(swd->sw_ictx, 0, axf->auth_hash->ctxsize); d923 1 a923 1 memset(swd->sw_octx, 0, axf->auth_hash->ctxsize); d933 1 a933 1 memset(swd->sw_ictx, 0, axf->auth_hash->ctxsize); @ 1.33 log @add an AES-CTR xform, from OpenBSD @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.32 2011/05/23 13:46:54 drochner Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.32 2011/05/23 13:46:54 drochner Exp $"); d95 1 a95 1 if (crd->crd_flags & CRD_F_IV_EXPLICIT) d97 5 a101 1 else { d136 2 a141 3 if (exf->reinit) exf->reinit(sw->sw_kschedule, iv); @ 1.32 log @-in the descriptor for encryption xforms, split the "blocksize" field into "blocksize" and "IV size" -add an "reinit" function pointer which, if set, means that the xform does its IV handling itself and doesn't want the default CBC handling by the framework (poor name, but left that way to avoid unecessary differences) This syncs with Open/FreeBSD, purpose is to allow non-CBC transforms. Refer to ivsize instead of blocksize where appropriate. (At this point, blocksize and ivsize are identical.) @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.31 2011/05/21 10:04:03 drochner Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.31 2011/05/21 10:04:03 drochner Exp $"); d705 3 d895 1 d1024 1 d1092 1 @ 1.31 log @fix a logics bug (which has been here from the beginning) which made that only 96 random bits were used for IV generation, this caused eg that the last 4 bytes of the IV in ESP/AES-CBC were constant, leaking kernel memory affects FAST_IPSEC only @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.30 2011/05/05 17:44:39 drochner Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.30 2011/05/05 17:44:39 drochner Exp $"); d80 1 a80 1 int i, k, j, blks; d85 2 d96 1 a96 1 memcpy(iv, crd->crd_iv, blks); d121 1 a121 1 COPYBACK(outtype, buf, crd->crd_inject, blks, iv); d127 1 a127 1 memcpy(iv, crd->crd_iv, blks); d130 1 a130 1 COPYDATA(outtype, buf, crd->crd_inject, blks, iv); d136 3 d140 10 a149 1 if (crd->crd_flags & CRD_F_ENCRYPT) { d200 9 a208 1 if (crd->crd_flags & CRD_F_ENCRYPT) { d278 9 a286 1 if (crd->crd_flags & CRD_F_ENCRYPT) { d343 9 a351 1 if (crd->crd_flags & CRD_F_ENCRYPT) { d412 9 a420 1 if (crd->crd_flags & CRD_F_ENCRYPT) { @ 1.30 log @support camellia-cbc by swcrypt @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.29 2011/02/25 20:13:10 drochner Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.29 2011/02/25 20:13:10 drochner Exp $"); d98 1 a98 1 i + sizeof (u_int32_t) < EALG_MAX_BLOCK_LEN; @ 1.29 log @make the use of SHA2-HMAC by FAST_IPSEC compliant to current standards: -RFC2104 says that the block size of the hash algorithm must be used for key/ipad/opad calculations. While formerly all ciphers used a block length of 64, SHA384 and SHA512 use 128 bytes. So we can't use the HMAC_BLOCK_LEN constant anymore. Add a new field to "struct auth_hash" for the per-cipher blocksize. -Due to this, there can't be a single "CRYPTO_SHA2_HMAC" external name anymore. Replace this by 3 for the 3 different keysizes. This was done by Open/FreeBSD before. -Also fix the number of authenticator bits used tor ESP and AH to conform to RFC4868, and remove uses of AH_HMAC_HASHLEN which did assume a fixed authenticator size of 12 bytes. FAST_IPSEC will not interoperate with KAME IPSEC anymore if sha2 is used, because the latter doesn't implement these standards. It should interoperate with at least modern Free/OpenBSD now. (I've only tested with NetBSD-current/FAST_IPSEC on both ends.) @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.28 2011/02/24 20:03:41 drochner Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.28 2011/02/24 20:03:41 drochner Exp $"); d656 3 d845 1 d973 1 d1040 1 @ 1.28 log @small modifications in dealing with the unknown result size of compression/ decompression: -seperate the IPCOMP specific rule that compression must not grow the data from general compression semantics: Introduce a special name CRYPTO_DEFLATE_COMP_NOGROW/comp_algo_deflate_nogrow to describe the IPCOMP semantics and use it there. (being here, fix the check so that equal size is considered failure as well as required by RFC2393) Customers of CRYPTO_DEFLATE_COMP/comp_algo_deflate now always get deflated data back, even if they are not smaller than the original. -allow to pass a "size hint" to the DEFLATE decompression function which is used for the initial buffer allocation. Due to the changes done there, additional allocations and extra copies are avoided if the initial allocation is sufficient. Set the size hint to MCLBYTES (=2k) in IPCOMP which should be good for many use cases. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.27 2011/02/10 21:00:42 drochner Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.27 2011/02/10 21:00:42 drochner Exp $"); d464 3 a466 1 case CRYPTO_SHA2_HMAC: d681 8 a688 11 case CRYPTO_SHA2_HMAC: if (cri->cri_klen == 256) axf = &swcr_auth_hash_hmac_sha2_256; else if (cri->cri_klen == 384) axf = &swcr_auth_hash_hmac_sha2_384; else if (cri->cri_klen == 512) axf = &swcr_auth_hash_hmac_sha2_512; else { swcr_freesession(NULL, i); return EINVAL; } d721 1 a721 1 HMAC_BLOCK_LEN - (cri->cri_klen / 8)); d730 1 a730 1 HMAC_BLOCK_LEN - (cri->cri_klen / 8)); d853 3 a855 1 case CRYPTO_SHA2_HMAC: d980 3 a982 1 case CRYPTO_SHA2_HMAC: d1040 3 a1042 1 REGISTER(CRYPTO_SHA2_HMAC); @ 1.27 log @Don't store temporary values in the opencrypto session data struct which can be shared by multiple threads -- pass them on the stack instead. Add some "const" to document this. (One _could_ use the session struct for temporary stuff with proper locking, but it seems unnecessary here.) Also remove the unused SW_crc member in the session struct. From Wolfgang Stukenbrock per PR kern/44472. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.26 2010/08/02 19:59:35 jakllsch Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.26 2010/08/02 19:59:35 jakllsch Exp $"); d538 2 a539 1 result = cxf->decompress(data, crd->crd_len, &out); d550 3 a552 2 if (crd->crd_flags & CRD_F_COMP) { if (result > crd->crd_len) { a555 1 } d792 5 d893 1 d993 1 d1047 1 @ 1.26 log @Consistently use a single CRYPTO_SESID2HID-like macro. Improve CRYPTO_DEBUG printing a bit: print pointers with %p print unsigned with %u rather than %d use CRYPTO_SESID2LID instead of just casting to uint32_t @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.25 2009/04/18 14:58:07 tsutsui Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.25 2009/04/18 14:58:07 tsutsui Exp $"); d63 2 a64 2 static int swcr_encdec(struct cryptodesc *, struct swcr_data *, void *, int); static int swcr_compdec(struct cryptodesc *, struct swcr_data *, void *, int); d73 1 a73 1 swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, void *bufv, d421 1 a421 1 struct swcr_data *sw, void *buf, int outtype) d515 2 a516 2 swcr_compdec(struct cryptodesc *crd, struct swcr_data *sw, void *buf, int outtype) d547 1 a547 1 sw->sw_size = result; d989 1 a989 1 crp->crp_buf, type)) != 0) a990 2 else crp->crp_olen = (int)sw->sw_size; @ 1.26.2.1 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.37 2011/05/26 21:50:03 drochner Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.37 2011/05/26 21:50:03 drochner Exp $"); a49 2 aesxcbc_ctx aesxcbcctx; AES_GMAC_CTX aesgmacctx; d63 2 a64 3 static int swcr_encdec(struct cryptodesc *, const struct swcr_data *, void *, int); static int swcr_compdec(struct cryptodesc *, const struct swcr_data *, void *, int, int *); static int swcr_combined(struct cryptop *, int); d73 1 a73 1 swcr_encdec(struct cryptodesc *crd, const struct swcr_data *sw, void *bufv, d80 1 a80 1 int i, k, j, blks, ivlen; a84 2 ivlen = exf->enc_xform->ivsize; KASSERT(exf->reinit ? ivlen <= blks : ivlen == blks); d93 3 a95 7 if (crd->crd_flags & CRD_F_IV_EXPLICIT) { memcpy(iv, crd->crd_iv, ivlen); if (exf->reinit) exf->reinit(sw->sw_kschedule, iv, 0); } else if (exf->reinit) { exf->reinit(sw->sw_kschedule, 0, iv); } else { d98 1 a98 1 i + sizeof (u_int32_t) <= EALG_MAX_BLOCK_LEN; d119 1 a119 1 COPYBACK(outtype, buf, crd->crd_inject, ivlen, iv); d125 1 a125 1 memcpy(iv, crd->crd_iv, ivlen); d128 1 a128 1 COPYDATA(outtype, buf, crd->crd_inject, ivlen, iv); a129 2 if (exf->reinit) exf->reinit(sw->sw_kschedule, iv, 0); d135 1 a135 10 if (exf->reinit) { for (i = crd->crd_skip; i < crd->crd_skip + crd->crd_len; i += blks) { if (crd->crd_flags & CRD_F_ENCRYPT) { exf->encrypt(sw->sw_kschedule, buf + i); } else { exf->decrypt(sw->sw_kschedule, buf + i); } } } else if (crd->crd_flags & CRD_F_ENCRYPT) { d186 1 a186 9 if (exf->reinit) { if (crd->crd_flags & CRD_F_ENCRYPT) { exf->encrypt(sw->sw_kschedule, blk); } else { exf->decrypt(sw->sw_kschedule, blk); } } else if (crd->crd_flags & CRD_F_ENCRYPT) { d256 1 a256 9 if (exf->reinit) { if (crd->crd_flags & CRD_F_ENCRYPT) { exf->encrypt(sw->sw_kschedule, idat); } else { exf->decrypt(sw->sw_kschedule, idat); } } else if (crd->crd_flags & CRD_F_ENCRYPT) { d313 1 a313 9 if (exf->reinit) { if (crd->crd_flags & CRD_F_ENCRYPT) { exf->encrypt(sw->sw_kschedule, blk); } else { exf->decrypt(sw->sw_kschedule, blk); } } else if (crd->crd_flags & CRD_F_ENCRYPT) { d374 1 a374 9 if (exf->reinit) { if (crd->crd_flags & CRD_F_ENCRYPT) { exf->encrypt(sw->sw_kschedule, idat); } else { exf->decrypt(sw->sw_kschedule, idat); } } else if (crd->crd_flags & CRD_F_ENCRYPT) { d421 1 a421 1 const struct swcr_data *sw, void *buf, int outtype) d433 1 a433 1 memcpy(&ctx, sw->sw_ictx, axf->ctxsize); d464 1 a464 3 case CRYPTO_SHA2_256_HMAC: case CRYPTO_SHA2_384_HMAC: case CRYPTO_SHA2_512_HMAC: d471 1 a471 1 memcpy(&ctx, sw->sw_octx, axf->ctxsize); a487 1 case CRYPTO_AES_XCBC_MAC_96: a511 137 * Apply a combined encryption-authentication transformation */ static int swcr_combined(struct cryptop *crp, int outtype) { uint32_t blkbuf[howmany(EALG_MAX_BLOCK_LEN, sizeof(uint32_t))]; u_char *blk = (u_char *)blkbuf; u_char aalg[AALG_MAX_RESULT_LEN]; u_char iv[EALG_MAX_BLOCK_LEN]; union authctx ctx; struct cryptodesc *crd, *crda = NULL, *crde = NULL; struct swcr_data *sw, *swa, *swe = NULL; const struct swcr_auth_hash *axf = NULL; const struct swcr_enc_xform *exf = NULL; void *buf = (void *)crp->crp_buf; uint32_t *blkp; int i, blksz = 0, ivlen = 0, len; for (crd = crp->crp_desc; crd; crd = crd->crd_next) { for (sw = swcr_sessions[crp->crp_sid & 0xffffffff]; sw && sw->sw_alg != crd->crd_alg; sw = sw->sw_next) ; if (sw == NULL) return (EINVAL); switch (sw->sw_alg) { case CRYPTO_AES_GCM_16: case CRYPTO_AES_GMAC: swe = sw; crde = crd; exf = swe->sw_exf; ivlen = exf->enc_xform->ivsize; break; case CRYPTO_AES_128_GMAC: case CRYPTO_AES_192_GMAC: case CRYPTO_AES_256_GMAC: swa = sw; crda = crd; axf = swa->sw_axf; if (swa->sw_ictx == 0) return (EINVAL); memcpy(&ctx, swa->sw_ictx, axf->ctxsize); blksz = axf->auth_hash->blocksize; break; default: return (EINVAL); } } if (crde == NULL || crda == NULL) return (EINVAL); if (outtype == CRYPTO_BUF_CONTIG) return (EINVAL); /* Initialize the IV */ if (crde->crd_flags & CRD_F_ENCRYPT) { /* IV explicitly provided ? */ if (crde->crd_flags & CRD_F_IV_EXPLICIT) { memcpy(iv, crde->crd_iv, ivlen); if (exf->reinit) exf->reinit(swe->sw_kschedule, iv, 0); } else if (exf->reinit) exf->reinit(swe->sw_kschedule, 0, iv); else arc4randbytes(iv, ivlen); /* Do we need to write the IV */ if (!(crde->crd_flags & CRD_F_IV_PRESENT)) COPYBACK(outtype, buf, crde->crd_inject, ivlen, iv); } else { /* Decryption */ /* IV explicitly provided ? */ if (crde->crd_flags & CRD_F_IV_EXPLICIT) memcpy(iv, crde->crd_iv, ivlen); else { /* Get IV off buf */ COPYDATA(outtype, buf, crde->crd_inject, ivlen, iv); } if (exf->reinit) exf->reinit(swe->sw_kschedule, iv, 0); } /* Supply MAC with IV */ if (axf->Reinit) axf->Reinit(&ctx, iv, ivlen); /* Supply MAC with AAD */ for (i = 0; i < crda->crd_len; i += blksz) { len = MIN(crda->crd_len - i, blksz); COPYDATA(outtype, buf, crda->crd_skip + i, len, blk); axf->Update(&ctx, blk, len); } /* Do encryption/decryption with MAC */ for (i = 0; i < crde->crd_len; i += blksz) { len = MIN(crde->crd_len - i, blksz); if (len < blksz) memset(blk, 0, blksz); COPYDATA(outtype, buf, crde->crd_skip + i, len, blk); if (crde->crd_flags & CRD_F_ENCRYPT) { exf->encrypt(swe->sw_kschedule, blk); axf->Update(&ctx, blk, len); } else { axf->Update(&ctx, blk, len); exf->decrypt(swe->sw_kschedule, blk); } COPYBACK(outtype, buf, crde->crd_skip + i, len, blk); } /* Do any required special finalization */ switch (crda->crd_alg) { case CRYPTO_AES_128_GMAC: case CRYPTO_AES_192_GMAC: case CRYPTO_AES_256_GMAC: /* length block */ memset(blk, 0, blksz); blkp = (uint32_t *)blk + 1; *blkp = htobe32(crda->crd_len * 8); blkp = (uint32_t *)blk + 3; *blkp = htobe32(crde->crd_len * 8); axf->Update(&ctx, blk, blksz); break; } /* Finalize MAC */ axf->Final(aalg, &ctx); /* Inject the authentication data */ if (outtype == CRYPTO_BUF_MBUF) COPYBACK(outtype, buf, crda->crd_inject, axf->auth_hash->authsize, aalg); else memcpy(crp->crp_mac, aalg, axf->auth_hash->authsize); return (0); } /* d515 2 a516 2 swcr_compdec(struct cryptodesc *crd, const struct swcr_data *sw, void *buf, int outtype, int *res_size) d538 1 a538 2 result = cxf->decompress(data, crd->crd_len, &out, *res_size); d547 1 a547 1 *res_size = (int)result; d549 2 a550 3 if (crd->crd_flags & CRD_F_COMP && sw->sw_alg == CRYPTO_DEFLATE_COMP_NOGROW && result >= crd->crd_len) { d554 1 a652 9 case CRYPTO_CAMELLIA_CBC: txf = &swcr_enc_xform_camellia; goto enccommon; case CRYPTO_AES_CTR: txf = &swcr_enc_xform_aes_ctr; goto enccommon; case CRYPTO_AES_GCM_16: txf = &swcr_enc_xform_aes_gcm; goto enccommon; a665 5 case CRYPTO_AES_GMAC: txf = &swcr_enc_xform_aes_gmac; (*swd)->sw_exf = txf; break; d678 11 a688 8 case CRYPTO_SHA2_256_HMAC: axf = &swcr_auth_hash_hmac_sha2_256; goto authcommon; case CRYPTO_SHA2_384_HMAC: axf = &swcr_auth_hash_hmac_sha2_384; goto authcommon; case CRYPTO_SHA2_512_HMAC: axf = &swcr_auth_hash_hmac_sha2_512; d700 1 a700 1 (*swd)->sw_ictx = malloc(axf->ctxsize, d707 1 a707 1 (*swd)->sw_octx = malloc(axf->ctxsize, d721 1 a721 1 axf->auth_hash->blocksize - (cri->cri_klen / 8)); d730 1 a730 1 axf->auth_hash->blocksize - (cri->cri_klen / 8)); d744 1 a744 1 (*swd)->sw_ictx = malloc(axf->ctxsize, d775 1 a775 1 (*swd)->sw_ictx = malloc(axf->ctxsize, a785 24 case CRYPTO_AES_XCBC_MAC_96: axf = &swcr_auth_hash_aes_xcbc_mac; goto auth4common; case CRYPTO_AES_128_GMAC: axf = &swcr_auth_hash_gmac_aes_128; goto auth4common; case CRYPTO_AES_192_GMAC: axf = &swcr_auth_hash_gmac_aes_192; goto auth4common; case CRYPTO_AES_256_GMAC: axf = &swcr_auth_hash_gmac_aes_256; auth4common: (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT); if ((*swd)->sw_ictx == NULL) { swcr_freesession(NULL, i); return ENOBUFS; } axf->Init((*swd)->sw_ictx); axf->Setkey((*swd)->sw_ictx, cri->cri_key, cri->cri_klen / 8); (*swd)->sw_axf = axf; break; a790 5 case CRYPTO_DEFLATE_COMP_NOGROW: cxf = &swcr_comp_algo_deflate_nogrow; (*swd)->sw_cxf = cxf; break; a836 3 case CRYPTO_CAMELLIA_CBC: case CRYPTO_AES_CTR: case CRYPTO_AES_GCM_16: a843 3 case CRYPTO_AES_GMAC: break; d848 1 a848 3 case CRYPTO_SHA2_256_HMAC: case CRYPTO_SHA2_384_HMAC: case CRYPTO_SHA2_512_HMAC: d855 1 a855 1 memset(swd->sw_ictx, 0, axf->ctxsize); d859 1 a859 1 memset(swd->sw_octx, 0, axf->ctxsize); d869 1 a869 1 memset(swd->sw_ictx, 0, axf->ctxsize); a879 4 case CRYPTO_AES_XCBC_MAC_96: case CRYPTO_AES_128_GMAC: case CRYPTO_AES_192_GMAC: case CRYPTO_AES_256_GMAC: a886 1 case CRYPTO_DEFLATE_COMP_NOGROW: a960 2 case CRYPTO_CAMELLIA_CBC: case CRYPTO_AES_CTR: d972 1 a972 3 case CRYPTO_SHA2_256_HMAC: case CRYPTO_SHA2_384_HMAC: case CRYPTO_SHA2_512_HMAC: a979 1 case CRYPTO_AES_XCBC_MAC_96: a984 8 case CRYPTO_AES_GCM_16: case CRYPTO_AES_GMAC: case CRYPTO_AES_128_GMAC: case CRYPTO_AES_192_GMAC: case CRYPTO_AES_256_GMAC: crp->crp_etype = swcr_combined(crp, type); goto done; a985 1 case CRYPTO_DEFLATE_COMP_NOGROW: d989 1 a989 1 crp->crp_buf, type, &crp->crp_olen)) != 0) d991 2 a1025 4 REGISTER(CRYPTO_CAMELLIA_CBC); REGISTER(CRYPTO_AES_CTR); REGISTER(CRYPTO_AES_GCM_16); REGISTER(CRYPTO_AES_GMAC); d1031 1 a1031 3 REGISTER(CRYPTO_SHA2_256_HMAC); REGISTER(CRYPTO_SHA2_384_HMAC); REGISTER(CRYPTO_SHA2_512_HMAC); a1038 4 REGISTER(CRYPTO_AES_XCBC_MAC_96); REGISTER(CRYPTO_AES_128_GMAC); REGISTER(CRYPTO_AES_192_GMAC); REGISTER(CRYPTO_AES_256_GMAC); a1040 1 REGISTER(CRYPTO_DEFLATE_COMP_NOGROW); @ 1.26.4.1 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.27 2011/02/10 21:00:42 drochner Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.27 2011/02/10 21:00:42 drochner Exp $"); d63 2 a64 2 static int swcr_encdec(struct cryptodesc *, const struct swcr_data *, void *, int); static int swcr_compdec(struct cryptodesc *, const struct swcr_data *, void *, int, int *); d73 1 a73 1 swcr_encdec(struct cryptodesc *crd, const struct swcr_data *sw, void *bufv, d421 1 a421 1 const struct swcr_data *sw, void *buf, int outtype) d515 2 a516 2 swcr_compdec(struct cryptodesc *crd, const struct swcr_data *sw, void *buf, int outtype, int *res_size) d547 1 a547 1 *res_size = (int)result; d989 1 a989 1 crp->crp_buf, type, &crp->crp_olen)) != 0) d991 2 @ 1.26.4.2 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD$ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD$"); d464 1 a464 3 case CRYPTO_SHA2_256_HMAC: case CRYPTO_SHA2_384_HMAC: case CRYPTO_SHA2_512_HMAC: d538 1 a538 2 result = cxf->decompress(data, crd->crd_len, &out, *res_size); d549 2 a550 3 if (crd->crd_flags & CRD_F_COMP && sw->sw_alg == CRYPTO_DEFLATE_COMP_NOGROW && result >= crd->crd_len) { d554 1 d678 11 a688 8 case CRYPTO_SHA2_256_HMAC: axf = &swcr_auth_hash_hmac_sha2_256; goto authcommon; case CRYPTO_SHA2_384_HMAC: axf = &swcr_auth_hash_hmac_sha2_384; goto authcommon; case CRYPTO_SHA2_512_HMAC: axf = &swcr_auth_hash_hmac_sha2_512; d721 1 a721 1 axf->auth_hash->blocksize - (cri->cri_klen / 8)); d730 1 a730 1 axf->auth_hash->blocksize - (cri->cri_klen / 8)); a790 5 case CRYPTO_DEFLATE_COMP_NOGROW: cxf = &swcr_comp_algo_deflate_nogrow; (*swd)->sw_cxf = cxf; break; d848 1 a848 3 case CRYPTO_SHA2_256_HMAC: case CRYPTO_SHA2_384_HMAC: case CRYPTO_SHA2_512_HMAC: a886 1 case CRYPTO_DEFLATE_COMP_NOGROW: d972 1 a972 3 case CRYPTO_SHA2_256_HMAC: case CRYPTO_SHA2_384_HMAC: case CRYPTO_SHA2_512_HMAC: a985 1 case CRYPTO_DEFLATE_COMP_NOGROW: d1029 1 a1029 3 REGISTER(CRYPTO_SHA2_256_HMAC); REGISTER(CRYPTO_SHA2_384_HMAC); REGISTER(CRYPTO_SHA2_512_HMAC); a1038 1 REGISTER(CRYPTO_DEFLATE_COMP_NOGROW); @ 1.25 log @Remove extra whitespace added by a stupid tool. XXX: more in src/sys/arch @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.24 2009/03/25 01:26:13 darran Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.24 2009/03/25 01:26:13 darran Exp $"); d1003 1 a1003 1 DPRINTF(("request %08x done\n", (uint32_t)crp)); @ 1.25.4.1 log @sync with head @ text @d1 1 a1 1 /* $NetBSD$ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD$"); d63 2 a64 2 static int swcr_encdec(struct cryptodesc *, const struct swcr_data *, void *, int); static int swcr_compdec(struct cryptodesc *, const struct swcr_data *, void *, int, int *); d73 1 a73 1 swcr_encdec(struct cryptodesc *crd, const struct swcr_data *sw, void *bufv, d421 1 a421 1 const struct swcr_data *sw, void *buf, int outtype) d464 1 a464 3 case CRYPTO_SHA2_256_HMAC: case CRYPTO_SHA2_384_HMAC: case CRYPTO_SHA2_512_HMAC: d515 2 a516 2 swcr_compdec(struct cryptodesc *crd, const struct swcr_data *sw, void *buf, int outtype, int *res_size) d538 1 a538 2 result = cxf->decompress(data, crd->crd_len, &out, *res_size); d547 1 a547 1 *res_size = (int)result; d549 2 a550 3 if (crd->crd_flags & CRD_F_COMP && sw->sw_alg == CRYPTO_DEFLATE_COMP_NOGROW && result >= crd->crd_len) { d554 1 d678 11 a688 8 case CRYPTO_SHA2_256_HMAC: axf = &swcr_auth_hash_hmac_sha2_256; goto authcommon; case CRYPTO_SHA2_384_HMAC: axf = &swcr_auth_hash_hmac_sha2_384; goto authcommon; case CRYPTO_SHA2_512_HMAC: axf = &swcr_auth_hash_hmac_sha2_512; d721 1 a721 1 axf->auth_hash->blocksize - (cri->cri_klen / 8)); d730 1 a730 1 axf->auth_hash->blocksize - (cri->cri_klen / 8)); a790 5 case CRYPTO_DEFLATE_COMP_NOGROW: cxf = &swcr_comp_algo_deflate_nogrow; (*swd)->sw_cxf = cxf; break; d848 1 a848 3 case CRYPTO_SHA2_256_HMAC: case CRYPTO_SHA2_384_HMAC: case CRYPTO_SHA2_512_HMAC: a886 1 case CRYPTO_DEFLATE_COMP_NOGROW: d972 1 a972 3 case CRYPTO_SHA2_256_HMAC: case CRYPTO_SHA2_384_HMAC: case CRYPTO_SHA2_512_HMAC: a985 1 case CRYPTO_DEFLATE_COMP_NOGROW: d989 1 a989 1 crp->crp_buf, type, &crp->crp_olen)) != 0) d991 2 d1003 1 a1003 1 DPRINTF(("request %p done\n", crp)); d1031 1 a1031 3 REGISTER(CRYPTO_SHA2_256_HMAC); REGISTER(CRYPTO_SHA2_384_HMAC); REGISTER(CRYPTO_SHA2_512_HMAC); a1040 1 REGISTER(CRYPTO_DEFLATE_COMP_NOGROW); @ 1.25.4.2 log @sync with head @ text @a49 2 aesxcbc_ctx aesxcbcctx; AES_GMAC_CTX aesgmacctx; a64 1 static int swcr_combined(struct cryptop *, int); d80 1 a80 1 int i, k, j, blks, ivlen; a84 2 ivlen = exf->enc_xform->ivsize; KASSERT(exf->reinit ? ivlen <= blks : ivlen == blks); d93 3 a95 7 if (crd->crd_flags & CRD_F_IV_EXPLICIT) { memcpy(iv, crd->crd_iv, ivlen); if (exf->reinit) exf->reinit(sw->sw_kschedule, iv, 0); } else if (exf->reinit) { exf->reinit(sw->sw_kschedule, 0, iv); } else { d98 1 a98 1 i + sizeof (u_int32_t) <= EALG_MAX_BLOCK_LEN; d119 1 a119 1 COPYBACK(outtype, buf, crd->crd_inject, ivlen, iv); d125 1 a125 1 memcpy(iv, crd->crd_iv, ivlen); d128 1 a128 1 COPYDATA(outtype, buf, crd->crd_inject, ivlen, iv); a129 2 if (exf->reinit) exf->reinit(sw->sw_kschedule, iv, 0); d135 1 a135 10 if (exf->reinit) { for (i = crd->crd_skip; i < crd->crd_skip + crd->crd_len; i += blks) { if (crd->crd_flags & CRD_F_ENCRYPT) { exf->encrypt(sw->sw_kschedule, buf + i); } else { exf->decrypt(sw->sw_kschedule, buf + i); } } } else if (crd->crd_flags & CRD_F_ENCRYPT) { d186 1 a186 9 if (exf->reinit) { if (crd->crd_flags & CRD_F_ENCRYPT) { exf->encrypt(sw->sw_kschedule, blk); } else { exf->decrypt(sw->sw_kschedule, blk); } } else if (crd->crd_flags & CRD_F_ENCRYPT) { d256 1 a256 9 if (exf->reinit) { if (crd->crd_flags & CRD_F_ENCRYPT) { exf->encrypt(sw->sw_kschedule, idat); } else { exf->decrypt(sw->sw_kschedule, idat); } } else if (crd->crd_flags & CRD_F_ENCRYPT) { d313 1 a313 9 if (exf->reinit) { if (crd->crd_flags & CRD_F_ENCRYPT) { exf->encrypt(sw->sw_kschedule, blk); } else { exf->decrypt(sw->sw_kschedule, blk); } } else if (crd->crd_flags & CRD_F_ENCRYPT) { d374 1 a374 9 if (exf->reinit) { if (crd->crd_flags & CRD_F_ENCRYPT) { exf->encrypt(sw->sw_kschedule, idat); } else { exf->decrypt(sw->sw_kschedule, idat); } } else if (crd->crd_flags & CRD_F_ENCRYPT) { d433 1 a433 1 memcpy(&ctx, sw->sw_ictx, axf->ctxsize); d473 1 a473 1 memcpy(&ctx, sw->sw_octx, axf->ctxsize); a489 1 case CRYPTO_AES_XCBC_MAC_96: a513 137 * Apply a combined encryption-authentication transformation */ static int swcr_combined(struct cryptop *crp, int outtype) { uint32_t blkbuf[howmany(EALG_MAX_BLOCK_LEN, sizeof(uint32_t))]; u_char *blk = (u_char *)blkbuf; u_char aalg[AALG_MAX_RESULT_LEN]; u_char iv[EALG_MAX_BLOCK_LEN]; union authctx ctx; struct cryptodesc *crd, *crda = NULL, *crde = NULL; struct swcr_data *sw, *swa, *swe = NULL; const struct swcr_auth_hash *axf = NULL; const struct swcr_enc_xform *exf = NULL; void *buf = (void *)crp->crp_buf; uint32_t *blkp; int i, blksz = 0, ivlen = 0, len; for (crd = crp->crp_desc; crd; crd = crd->crd_next) { for (sw = swcr_sessions[crp->crp_sid & 0xffffffff]; sw && sw->sw_alg != crd->crd_alg; sw = sw->sw_next) ; if (sw == NULL) return (EINVAL); switch (sw->sw_alg) { case CRYPTO_AES_GCM_16: case CRYPTO_AES_GMAC: swe = sw; crde = crd; exf = swe->sw_exf; ivlen = exf->enc_xform->ivsize; break; case CRYPTO_AES_128_GMAC: case CRYPTO_AES_192_GMAC: case CRYPTO_AES_256_GMAC: swa = sw; crda = crd; axf = swa->sw_axf; if (swa->sw_ictx == 0) return (EINVAL); memcpy(&ctx, swa->sw_ictx, axf->ctxsize); blksz = axf->auth_hash->blocksize; break; default: return (EINVAL); } } if (crde == NULL || crda == NULL) return (EINVAL); if (outtype == CRYPTO_BUF_CONTIG) return (EINVAL); /* Initialize the IV */ if (crde->crd_flags & CRD_F_ENCRYPT) { /* IV explicitly provided ? */ if (crde->crd_flags & CRD_F_IV_EXPLICIT) { memcpy(iv, crde->crd_iv, ivlen); if (exf->reinit) exf->reinit(swe->sw_kschedule, iv, 0); } else if (exf->reinit) exf->reinit(swe->sw_kschedule, 0, iv); else arc4randbytes(iv, ivlen); /* Do we need to write the IV */ if (!(crde->crd_flags & CRD_F_IV_PRESENT)) COPYBACK(outtype, buf, crde->crd_inject, ivlen, iv); } else { /* Decryption */ /* IV explicitly provided ? */ if (crde->crd_flags & CRD_F_IV_EXPLICIT) memcpy(iv, crde->crd_iv, ivlen); else { /* Get IV off buf */ COPYDATA(outtype, buf, crde->crd_inject, ivlen, iv); } if (exf->reinit) exf->reinit(swe->sw_kschedule, iv, 0); } /* Supply MAC with IV */ if (axf->Reinit) axf->Reinit(&ctx, iv, ivlen); /* Supply MAC with AAD */ for (i = 0; i < crda->crd_len; i += blksz) { len = MIN(crda->crd_len - i, blksz); COPYDATA(outtype, buf, crda->crd_skip + i, len, blk); axf->Update(&ctx, blk, len); } /* Do encryption/decryption with MAC */ for (i = 0; i < crde->crd_len; i += blksz) { len = MIN(crde->crd_len - i, blksz); if (len < blksz) memset(blk, 0, blksz); COPYDATA(outtype, buf, crde->crd_skip + i, len, blk); if (crde->crd_flags & CRD_F_ENCRYPT) { exf->encrypt(swe->sw_kschedule, blk); axf->Update(&ctx, blk, len); } else { axf->Update(&ctx, blk, len); exf->decrypt(swe->sw_kschedule, blk); } COPYBACK(outtype, buf, crde->crd_skip + i, len, blk); } /* Do any required special finalization */ switch (crda->crd_alg) { case CRYPTO_AES_128_GMAC: case CRYPTO_AES_192_GMAC: case CRYPTO_AES_256_GMAC: /* length block */ memset(blk, 0, blksz); blkp = (uint32_t *)blk + 1; *blkp = htobe32(crda->crd_len * 8); blkp = (uint32_t *)blk + 3; *blkp = htobe32(crde->crd_len * 8); axf->Update(&ctx, blk, blksz); break; } /* Finalize MAC */ axf->Final(aalg, &ctx); /* Inject the authentication data */ if (outtype == CRYPTO_BUF_MBUF) COPYBACK(outtype, buf, crda->crd_inject, axf->auth_hash->authsize, aalg); else memcpy(crp->crp_mac, aalg, axf->auth_hash->authsize); return (0); } /* a655 9 case CRYPTO_CAMELLIA_CBC: txf = &swcr_enc_xform_camellia; goto enccommon; case CRYPTO_AES_CTR: txf = &swcr_enc_xform_aes_ctr; goto enccommon; case CRYPTO_AES_GCM_16: txf = &swcr_enc_xform_aes_gcm; goto enccommon; a668 5 case CRYPTO_AES_GMAC: txf = &swcr_enc_xform_aes_gmac; (*swd)->sw_exf = txf; break; d700 1 a700 1 (*swd)->sw_ictx = malloc(axf->ctxsize, d707 1 a707 1 (*swd)->sw_octx = malloc(axf->ctxsize, d744 1 a744 1 (*swd)->sw_ictx = malloc(axf->ctxsize, d775 1 a775 1 (*swd)->sw_ictx = malloc(axf->ctxsize, a785 24 case CRYPTO_AES_XCBC_MAC_96: axf = &swcr_auth_hash_aes_xcbc_mac; goto auth4common; case CRYPTO_AES_128_GMAC: axf = &swcr_auth_hash_gmac_aes_128; goto auth4common; case CRYPTO_AES_192_GMAC: axf = &swcr_auth_hash_gmac_aes_192; goto auth4common; case CRYPTO_AES_256_GMAC: axf = &swcr_auth_hash_gmac_aes_256; auth4common: (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT); if ((*swd)->sw_ictx == NULL) { swcr_freesession(NULL, i); return ENOBUFS; } axf->Init((*swd)->sw_ictx); axf->Setkey((*swd)->sw_ictx, cri->cri_key, cri->cri_klen / 8); (*swd)->sw_axf = axf; break; a841 3 case CRYPTO_CAMELLIA_CBC: case CRYPTO_AES_CTR: case CRYPTO_AES_GCM_16: a848 3 case CRYPTO_AES_GMAC: break; d862 1 a862 1 memset(swd->sw_ictx, 0, axf->ctxsize); d866 1 a866 1 memset(swd->sw_octx, 0, axf->ctxsize); d876 1 a876 1 memset(swd->sw_ictx, 0, axf->ctxsize); a886 4 case CRYPTO_AES_XCBC_MAC_96: case CRYPTO_AES_128_GMAC: case CRYPTO_AES_192_GMAC: case CRYPTO_AES_256_GMAC: a968 2 case CRYPTO_CAMELLIA_CBC: case CRYPTO_AES_CTR: a989 1 case CRYPTO_AES_XCBC_MAC_96: a994 8 case CRYPTO_AES_GCM_16: case CRYPTO_AES_GMAC: case CRYPTO_AES_128_GMAC: case CRYPTO_AES_192_GMAC: case CRYPTO_AES_256_GMAC: crp->crp_etype = swcr_combined(crp, type); goto done; a1034 4 REGISTER(CRYPTO_CAMELLIA_CBC); REGISTER(CRYPTO_AES_CTR); REGISTER(CRYPTO_AES_GCM_16); REGISTER(CRYPTO_AES_GMAC); a1049 4 REGISTER(CRYPTO_AES_XCBC_MAC_96); REGISTER(CRYPTO_AES_128_GMAC); REGISTER(CRYPTO_AES_192_GMAC); REGISTER(CRYPTO_AES_256_GMAC); @ 1.25.4.3 log @sync with head @ text @a854 3 case CRYPTO_AES_GMAC: txf = &swcr_enc_xform_aes_gmac; goto enccommon; d868 5 a1072 1 case CRYPTO_AES_GMAC: d1080 3 @ 1.25.2.1 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD$ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD$"); d1003 1 a1003 1 DPRINTF(("request %p done\n", crp)); @ 1.24 log @Fixes PR kern/41069 and PR kern/41070. Extends the Opencrypto API to allow the destination buffer size to be specified when its not the same size as the input buffer (i.e. for operations like compress and decompress). The crypto_op and crypt_n_op structures gain a u_int dst_len field. The session_op structure gains a comp_alg field to specify a compression algorithm. Moved four ioctls to new ids; CIOCGSESSION, CIOCNGSESSION, CIOCCRYPT, and CIOCNCRYPTM. Added four backward compatible ioctls; OCIOCGSESSION, OCIOCNGSESSION, OCIOCCRYPT, and OCIOCNCRYPTM. Backward compatibility is maintained in ocryptodev.h and ocryptodev.c which implement the original ioctls and set dst_len and comp_alg to 0. Adds user-space access to compression features. Adds software gzip support (CRYPTO_GZIP_COMP). Adds the fast version of crc32 from zlib to libkern. This should be generally useful and provide a place to start normalizing the various crc32 routines in the kernel. The crc32 routine is used in this patch to support GZIP. With input and support from tls@@NetBSD.org. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.23 2009/03/18 17:06:53 cegger Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.23 2009/03/18 17:06:53 cegger Exp $"); d94 1 a94 1 memcpy( iv, crd->crd_iv, blks); d102 1 a102 1 memcpy( iv + i, &temp, sizeof(u_int32_t)); d125 1 a125 1 memcpy( iv, crd->crd_iv, blks); d197 1 a197 1 memcpy( iv, blk, blks); d205 1 a205 1 memcpy( piv, blk, blks); d207 1 a207 1 memcpy( iv, blk, blks); d216 1 a216 1 memcpy( iv, piv, blks); d269 1 a269 1 memcpy( piv, idat, blks); d271 1 a271 1 memcpy( iv, idat, blks); d280 1 a280 1 memcpy( iv, piv, blks); d324 1 a324 1 memcpy( iv, blk, blks); d332 1 a332 1 memcpy( piv, blk, blks); d334 1 a334 1 memcpy( iv, blk, blks); d343 1 a343 1 memcpy( iv, piv, blks); d387 1 a387 1 memcpy( piv, idat, blks); d389 1 a389 1 memcpy( iv, idat, blks); d398 1 a398 1 memcpy( iv, piv, blks); d433 1 a433 1 memcpy( &ctx, sw->sw_ictx, axf->auth_hash->ctxsize); d471 1 a471 1 memcpy( &ctx, sw->sw_octx, axf->auth_hash->ctxsize); d503 1 a503 1 memcpy( crp->crp_mac, aalg, axf->auth_hash->authsize); d615 1 a615 1 memcpy( swd, swcr_sessions, d760 1 a760 1 memcpy( (*swd)->sw_octx, cri->cri_key, cri->cri_klen / 8); @ 1.23 log @bcopy -> memcpy @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.22 2009/03/18 16:00:24 cegger Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.22 2009/03/18 16:00:24 cegger Exp $"); a562 18 } else { struct uio *uio = (struct uio *)buf; int ind; adj = crd->crd_len - result; ind = uio->uio_iovcnt - 1; while (adj > 0 && ind >= 0) { if (adj < uio->uio_iov[ind].iov_len) { uio->uio_iov[ind].iov_len -= adj; break; } adj -= uio->uio_iov[ind].iov_len; uio->uio_iov[ind].iov_len = 0; ind--; uio->uio_iovcnt--; } d564 1 d790 5 d887 1 d986 2 d1041 1 @ 1.22 log @bzero -> memset @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.21 2008/12/17 20:51:38 cegger Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.21 2008/12/17 20:51:38 cegger Exp $"); d94 1 a94 1 bcopy(crd->crd_iv, iv, blks); d102 1 a102 1 bcopy(&temp, iv + i, sizeof(u_int32_t)); d125 1 a125 1 bcopy(crd->crd_iv, iv, blks); d197 1 a197 1 bcopy(blk, iv, blks); d205 1 a205 1 bcopy(blk, piv, blks); d207 1 a207 1 bcopy(blk, iv, blks); d216 1 a216 1 bcopy(piv, iv, blks); d269 1 a269 1 bcopy(idat, piv, blks); d271 1 a271 1 bcopy(idat, iv, blks); d280 1 a280 1 bcopy(piv, iv, blks); d324 1 a324 1 bcopy(blk, iv, blks); d332 1 a332 1 bcopy(blk, piv, blks); d334 1 a334 1 bcopy(blk, iv, blks); d343 1 a343 1 bcopy(piv, iv, blks); d387 1 a387 1 bcopy(idat, piv, blks); d389 1 a389 1 bcopy(idat, iv, blks); d398 1 a398 1 bcopy(piv, iv, blks); d433 1 a433 1 bcopy(sw->sw_ictx, &ctx, axf->auth_hash->ctxsize); d471 1 a471 1 bcopy(sw->sw_octx, &ctx, axf->auth_hash->ctxsize); d503 1 a503 1 bcopy(aalg, crp->crp_mac, axf->auth_hash->authsize); d632 1 a632 1 bcopy(swcr_sessions, swd, d777 1 a777 1 bcopy(cri->cri_key, (*swd)->sw_octx, cri->cri_klen / 8); @ 1.21 log @kill MALLOC and FREE macros. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.20 2008/02/04 00:35:34 tls Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.20 2008/02/04 00:35:34 tls Exp $"); d628 1 a628 1 bzero(swd, swcr_sesnum * sizeof(struct swcr_data *)); d649 1 a649 1 bzero(*swd, sizeof(struct swcr_data)); d867 1 a867 1 bzero(swd->sw_ictx, axf->auth_hash->ctxsize); d871 1 a871 1 bzero(swd->sw_octx, axf->auth_hash->ctxsize); d881 1 a881 1 bzero(swd->sw_ictx, axf->auth_hash->ctxsize); d885 1 a885 1 bzero(swd->sw_octx, swd->sw_klen); @ 1.21.2.1 log @Sync with HEAD. Commit is split, to avoid a "too many arguments" protocol error. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.25 2009/04/18 14:58:07 tsutsui Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.25 2009/04/18 14:58:07 tsutsui Exp $"); d94 1 a94 1 memcpy(iv, crd->crd_iv, blks); d102 1 a102 1 memcpy(iv + i, &temp, sizeof(u_int32_t)); d125 1 a125 1 memcpy(iv, crd->crd_iv, blks); d197 1 a197 1 memcpy(iv, blk, blks); d205 1 a205 1 memcpy(piv, blk, blks); d207 1 a207 1 memcpy(iv, blk, blks); d216 1 a216 1 memcpy(iv, piv, blks); d269 1 a269 1 memcpy(piv, idat, blks); d271 1 a271 1 memcpy(iv, idat, blks); d280 1 a280 1 memcpy(iv, piv, blks); d324 1 a324 1 memcpy(iv, blk, blks); d332 1 a332 1 memcpy(piv, blk, blks); d334 1 a334 1 memcpy(iv, blk, blks); d343 1 a343 1 memcpy(iv, piv, blks); d387 1 a387 1 memcpy(piv, idat, blks); d389 1 a389 1 memcpy(iv, idat, blks); d398 1 a398 1 memcpy(iv, piv, blks); d433 1 a433 1 memcpy(&ctx, sw->sw_ictx, axf->auth_hash->ctxsize); d471 1 a471 1 memcpy(&ctx, sw->sw_octx, axf->auth_hash->ctxsize); d503 1 a503 1 memcpy(crp->crp_mac, aalg, axf->auth_hash->authsize); d563 18 a581 1 /* Don't adjust the iov_len, it breaks the kmem_free */ d628 1 a628 1 memset(swd, 0, swcr_sesnum * sizeof(struct swcr_data *)); d632 1 a632 1 memcpy(swd, swcr_sessions, d649 1 a649 1 memset(*swd, 0, sizeof(struct swcr_data)); d777 1 a777 1 memcpy((*swd)->sw_octx, cri->cri_key, cri->cri_klen / 8); a806 5 case CRYPTO_GZIP_COMP: cxf = &swcr_comp_algo_gzip; (*swd)->sw_cxf = cxf; break; d867 1 a867 1 memset(swd->sw_ictx, 0, axf->auth_hash->ctxsize); d871 1 a871 1 memset(swd->sw_octx, 0, axf->auth_hash->ctxsize); d881 1 a881 1 memset(swd->sw_ictx, 0, axf->auth_hash->ctxsize); d885 1 a885 1 memset(swd->sw_octx, 0, swd->sw_klen); a898 1 case CRYPTO_GZIP_COMP: a996 2 case CRYPTO_GZIP_COMP: DPRINTF(("swcr_process: compdec for %d\n", sw->sw_alg)); a1049 1 REGISTER(CRYPTO_GZIP_COMP); @ 1.20 log @Rework opencrypto to use a spin mutex (crypto_mtx) instead of "splcrypto" (actually splnet) and condvars instead of tsleep/wakeup. Fix a few miscellaneous problems and add some debugging printfs while there. Restore set of CRYPTO_F_DONE in crypto_done() which was lost at some point after this code came from FreeBSD -- it made it impossible to wait properly for a condition. Add flags analogous to the "crp" flags to the key operation's krp struct. Add a new flag, CRYPTO_F_ONRETQ which tells us a request finished before the kthread had a chance to dequeue it and call its callback -- this was letting requests stick on the queues before even though done and copied out. Callers of crypto_newsession() or crypto_freesession() must now take the mutex. Change netipsec to do so. Dispatch takes the mutex itself as needed. This was tested fairly extensively with the cryptosoft backend and lightly with a new hardware driver. It has not been tested with FAST_IPSEC; I am unable to ascertain whether FAST_IPSEC currently works at all in our tree. pjd@@FreeBSD.ORG, ad@@NetBSD.ORG, and darran@@snark.us pointed me in the right direction several times in the course of this. Remaining bugs are mine alone. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.19 2008/02/02 04:46:29 tls Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.19 2008/02/02 04:46:29 tls Exp $"); d540 1 a540 1 FREE(data, M_CRYPTO_DATA); d552 1 a552 1 FREE(out, M_CRYPTO_DATA); d583 1 a583 1 FREE(out, M_CRYPTO_DATA); d903 1 a903 1 FREE(swd, M_CRYPTO_DATA); @ 1.20.26.1 log @bring matt-nb5-mips64 up to date with netbsd-5-1-RELEASE (except compat). @ text @d1 1 a1 1 /* $NetBSD$ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD$"); d563 18 a581 1 /* Don't adjust the iov_len, it breaks the kmem_free */ a806 5 case CRYPTO_GZIP_COMP: cxf = &swcr_comp_algo_gzip; (*swd)->sw_cxf = cxf; break; a898 1 case CRYPTO_GZIP_COMP: a996 2 case CRYPTO_GZIP_COMP: DPRINTF(("swcr_process: compdec for %d\n", sw->sw_alg)); a1049 1 REGISTER(CRYPTO_GZIP_COMP); @ 1.20.10.1 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.20 2008/02/04 00:35:34 tls Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.20 2008/02/04 00:35:34 tls Exp $"); d94 1 a94 1 memcpy(iv, crd->crd_iv, blks); d102 1 a102 1 memcpy(iv + i, &temp, sizeof(u_int32_t)); d125 1 a125 1 memcpy(iv, crd->crd_iv, blks); d197 1 a197 1 memcpy(iv, blk, blks); d205 1 a205 1 memcpy(piv, blk, blks); d207 1 a207 1 memcpy(iv, blk, blks); d216 1 a216 1 memcpy(iv, piv, blks); d269 1 a269 1 memcpy(piv, idat, blks); d271 1 a271 1 memcpy(iv, idat, blks); d280 1 a280 1 memcpy(iv, piv, blks); d324 1 a324 1 memcpy(iv, blk, blks); d332 1 a332 1 memcpy(piv, blk, blks); d334 1 a334 1 memcpy(iv, blk, blks); d343 1 a343 1 memcpy(iv, piv, blks); d387 1 a387 1 memcpy(piv, idat, blks); d389 1 a389 1 memcpy(iv, idat, blks); d398 1 a398 1 memcpy(iv, piv, blks); d433 1 a433 1 memcpy(&ctx, sw->sw_ictx, axf->auth_hash->ctxsize); d471 1 a471 1 memcpy(&ctx, sw->sw_octx, axf->auth_hash->ctxsize); d503 1 a503 1 memcpy(crp->crp_mac, aalg, axf->auth_hash->authsize); d540 1 a540 1 free(data, M_CRYPTO_DATA); d552 1 a552 1 free(out, M_CRYPTO_DATA); d563 18 a581 1 /* Don't adjust the iov_len, it breaks the kmem_free */ d583 1 a583 1 free(out, M_CRYPTO_DATA); d628 1 a628 1 memset(swd, 0, swcr_sesnum * sizeof(struct swcr_data *)); d632 1 a632 1 memcpy(swd, swcr_sessions, d649 1 a649 1 memset(*swd, 0, sizeof(struct swcr_data)); d777 1 a777 1 memcpy((*swd)->sw_octx, cri->cri_key, cri->cri_klen / 8); a806 5 case CRYPTO_GZIP_COMP: cxf = &swcr_comp_algo_gzip; (*swd)->sw_cxf = cxf; break; d867 1 a867 1 memset(swd->sw_ictx, 0, axf->auth_hash->ctxsize); d871 1 a871 1 memset(swd->sw_octx, 0, axf->auth_hash->ctxsize); d881 1 a881 1 memset(swd->sw_ictx, 0, axf->auth_hash->ctxsize); d885 1 a885 1 memset(swd->sw_octx, 0, swd->sw_klen); a898 1 case CRYPTO_GZIP_COMP: d903 1 a903 1 free(swd, M_CRYPTO_DATA); a996 2 case CRYPTO_GZIP_COMP: DPRINTF(("swcr_process: compdec for %d\n", sw->sw_alg)); a1049 1 REGISTER(CRYPTO_GZIP_COMP); @ 1.20.10.2 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.20.10.1 2009/05/04 08:14:24 yamt Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.20.10.1 2009/05/04 08:14:24 yamt Exp $"); d1003 1 a1003 1 DPRINTF(("request %p done\n", crp)); @ 1.20.20.1 log @Pull up following revision(s) (requested by tls in ticket #611): sys/lib/libkern/Makefile: patch sys/lib/libkern/crc32.c: revision 1.1 sys/lib/libkern/crc32.h: revision 1.1 sys/lib/libkern/libkern.h: revision 1.89 sys/lib/libkern/arch/i386/Makefile.inc: revision 1.28 sys/net/zlib.h: revision 1.14 via patch sys/opencrypto/crypto.c: revision 1.33 sys/opencrypto/cryptodev.c: revision 1.46 sys/opencrypto/cryptodev.h: revision 1.16 sys/opencrypto/cryptosoft.c: revision 1.24 sys/opencrypto/cryptosoft.h: revision 1.6 sys/opencrypto/deflate.h: revision 1.6 sys/opencrypto/cryptosoft_xform.c: revision 1.12 sys/opencrypto/deflate.c: revision 1.13 sys/opencrypto/files.opencrypto: revision 1.20 sys/opencrypto/ocryptodev.c: revision 1.1 sys/opencrypto/ocryptodev.h: revision 1.1 sys/opencrypto/xform.c: revision 1.18 sys/opencrypto/xform.h: revision 1.10 Fixes PR kern/41069 and PR kern/41070. Extends the Opencrypto API to allow the destination buffer size to be specified when its not the same size as the input buffer (i.e. for operations like compress and decompress). The crypto_op and crypt_n_op structures gain a u_int dst_len field. The session_op structure gains a comp_alg field to specify a compression algorithm. Moved four ioctls to new ids; CIOCGSESSION, CIOCNGSESSION, CIOCCRYPT, and CIOCNCRYPTM. Added four backward compatible ioctls; OCIOCGSESSION, OCIOCNGSESSION, OCIOCCRYPT, and OCIOCNCRYPTM. Backward compatibility is maintained in ocryptodev.h and ocryptodev.c which implement the original ioctls and set dst_len and comp_alg to 0. Adds user-space access to compression features. Adds software gzip support (CRYPTO_GZIP_COMP). Adds the fast version of crc32 from zlib to libkern. This should be generally useful and provide a place to start normalizing the various crc32 routines in the kernel. The crc32 routine is used in this patch to support GZIP. With input and support from tls@@NetBSD.org. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.20 2008/02/04 00:35:34 tls Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.20 2008/02/04 00:35:34 tls Exp $"); d563 18 a581 1 /* Don't adjust the iov_len, it breaks the kmem_free */ a806 5 case CRYPTO_GZIP_COMP: cxf = &swcr_comp_algo_gzip; (*swd)->sw_cxf = cxf; break; a898 1 case CRYPTO_GZIP_COMP: a996 2 case CRYPTO_GZIP_COMP: DPRINTF(("swcr_process: compdec for %d\n", sw->sw_alg)); a1049 1 REGISTER(CRYPTO_GZIP_COMP); @ 1.20.18.1 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.21 2008/12/17 20:51:38 cegger Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.21 2008/12/17 20:51:38 cegger Exp $"); d540 1 a540 1 free(data, M_CRYPTO_DATA); d552 1 a552 1 free(out, M_CRYPTO_DATA); d583 1 a583 1 free(out, M_CRYPTO_DATA); d903 1 a903 1 free(swd, M_CRYPTO_DATA); @ 1.20.18.2 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.20.18.1 2009/01/19 13:20:20 skrll Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.20.18.1 2009/01/19 13:20:20 skrll Exp $"); d94 1 a94 1 memcpy(iv, crd->crd_iv, blks); d102 1 a102 1 memcpy(iv + i, &temp, sizeof(u_int32_t)); d125 1 a125 1 memcpy(iv, crd->crd_iv, blks); d197 1 a197 1 memcpy(iv, blk, blks); d205 1 a205 1 memcpy(piv, blk, blks); d207 1 a207 1 memcpy(iv, blk, blks); d216 1 a216 1 memcpy(iv, piv, blks); d269 1 a269 1 memcpy(piv, idat, blks); d271 1 a271 1 memcpy(iv, idat, blks); d280 1 a280 1 memcpy(iv, piv, blks); d324 1 a324 1 memcpy(iv, blk, blks); d332 1 a332 1 memcpy(piv, blk, blks); d334 1 a334 1 memcpy(iv, blk, blks); d343 1 a343 1 memcpy(iv, piv, blks); d387 1 a387 1 memcpy(piv, idat, blks); d389 1 a389 1 memcpy(iv, idat, blks); d398 1 a398 1 memcpy(iv, piv, blks); d433 1 a433 1 memcpy(&ctx, sw->sw_ictx, axf->auth_hash->ctxsize); d471 1 a471 1 memcpy(&ctx, sw->sw_octx, axf->auth_hash->ctxsize); d503 1 a503 1 memcpy(crp->crp_mac, aalg, axf->auth_hash->authsize); d563 18 a581 1 /* Don't adjust the iov_len, it breaks the kmem_free */ d628 1 a628 1 memset(swd, 0, swcr_sesnum * sizeof(struct swcr_data *)); d632 1 a632 1 memcpy(swd, swcr_sessions, d649 1 a649 1 memset(*swd, 0, sizeof(struct swcr_data)); d777 1 a777 1 memcpy((*swd)->sw_octx, cri->cri_key, cri->cri_klen / 8); a806 5 case CRYPTO_GZIP_COMP: cxf = &swcr_comp_algo_gzip; (*swd)->sw_cxf = cxf; break; d867 1 a867 1 memset(swd->sw_ictx, 0, axf->auth_hash->ctxsize); d871 1 a871 1 memset(swd->sw_octx, 0, axf->auth_hash->ctxsize); d881 1 a881 1 memset(swd->sw_ictx, 0, axf->auth_hash->ctxsize); d885 1 a885 1 memset(swd->sw_octx, 0, swd->sw_klen); a898 1 case CRYPTO_GZIP_COMP: a996 2 case CRYPTO_GZIP_COMP: DPRINTF(("swcr_process: compdec for %d\n", sw->sw_alg)); a1049 1 REGISTER(CRYPTO_GZIP_COMP); @ 1.20.6.1 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD$ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD$"); d540 1 a540 1 free(data, M_CRYPTO_DATA); d552 1 a552 1 free(out, M_CRYPTO_DATA); d583 1 a583 1 free(out, M_CRYPTO_DATA); d903 1 a903 1 free(swd, M_CRYPTO_DATA); @ 1.19 log @Add CRYPTO_*_HMAC_96 defines -- missed this file in previous commit. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.18 2008/02/01 04:52:35 tls Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.18 2008/02/01 04:52:35 tls Exp $"); d36 1 d1012 1 @ 1.18 log @This code never worked on a released version of FreeBSD in the form it's been in in our tree, and certainly does not work on any version of FreeBSD now. Run through unifdef -D__NetBSD__ -U__FreeBSD__ yielding a small reduction of size and a dramatic improvement in readability. No, this does not yield any meaningful decrease in patchability (unlike mechanical changes that touch live source lines) -- try it and see. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.17 2007/03/04 06:03:40 christos Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.17 2007/03/04 06:03:40 christos Exp $"); d460 1 d462 1 d465 1 d683 3 d689 3 d710 3 d714 1 d856 1 d858 1 d861 1 d979 1 d981 1 d984 1 d1035 1 d1037 1 d1040 1 @ 1.17 log @Kill caddr_t; there will be some MI fallout, but it will be fixed shortly. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.16 2007/02/17 00:28:25 daniel Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.16 2007/02/17 00:28:25 daniel Exp $"); a293 113 #ifdef __FreeBSD__ struct iovec *iov; /* Find beginning of data */ iov = cuio_getptr(uio, crd->crd_skip, &k); if (iov == NULL) return EINVAL; i = crd->crd_len; while (i > 0) { /* * If there's insufficient data at the end of * an iovec, we have to do some copying. */ if (iov->iov_len < k + blks && iov->iov_len != k) { cuio_copydata(uio, k, blks, blk); /* Actual encryption/decryption */ if (crd->crd_flags & CRD_F_ENCRYPT) { /* XOR with previous block */ for (j = 0; j < blks; j++) blk[j] ^= ivp[j]; exf->encrypt(sw->sw_kschedule, blk); /* * Keep encrypted block for XOR'ing * with next block */ bcopy(blk, iv, blks); ivp = iv; } else { /* decrypt */ /* * Keep encrypted block for XOR'ing * with next block */ if (ivp == iv) bcopy(blk, piv, blks); else bcopy(blk, iv, blks); exf->decrypt(sw->sw_kschedule, blk); /* XOR with previous block */ for (j = 0; j < blks; j++) blk[j] ^= ivp[j]; if (ivp == iv) bcopy(piv, iv, blks); else ivp = iv; } /* Copy back decrypted block */ cuio_copyback(uio, k, blks, blk); /* Advance pointer */ iov = cuio_getptr(uio, k + blks, &k); if (iov == NULL) return EINVAL; i -= blks; /* Could be done... */ if (i == 0) break; } /* * Warning: idat may point to garbage here, but * we only use it in the while() loop, only if * there are indeed enough data. */ idat = (char *)iov->iov_base + k; while (iov->iov_len >= k + blks && i > 0) { if (crd->crd_flags & CRD_F_ENCRYPT) { /* XOR with previous block/IV */ for (j = 0; j < blks; j++) idat[j] ^= ivp[j]; exf->encrypt(sw->sw_kschedule, idat); ivp = idat; } else { /* decrypt */ /* * Keep encrypted block to be used * in next block's processing. */ if (ivp == iv) bcopy(idat, piv, blks); else bcopy(idat, iv, blks); exf->decrypt(sw->sw_kschedule, idat); /* XOR with previous block/IV */ for (j = 0; j < blks; j++) idat[j] ^= ivp[j]; if (ivp == iv) bcopy(piv, iv, blks); else ivp = iv; } idat += blks; k += blks; i -= blks; } } return 0; /* Done with mbuf encryption/decryption */ #else /* !freebsd iov */ a407 1 #endif a445 4 #ifdef __FreeBSD__ /*XXX FIXME: handle iov case*/ return EINVAL; #else a452 1 #endif a1028 3 #ifdef __FreeBSD__ SYSINIT(cryptosoft_init, SI_SUB_PSEUDO, SI_ORDER_ANY, swcr_init, NULL) #endif a1029 1 #ifdef __NetBSD__ a1040 1 #endif /* __NetBSD__ */ @ 1.17.16.1 log @sync with HEAD @ text @d1 1 a1 1 /* cryptosoft.c,v 1.17 2007/03/04 06:03:40 christos Exp */ d27 1 a27 1 __KERNEL_RCSID(0, "cryptosoft.c,v 1.17 2007/03/04 06:03:40 christos Exp"); a35 1 #include "opt_ocf.h" d294 113 d521 1 d560 4 d571 1 a578 1 case CRYPTO_MD5_HMAC_96: a579 1 case CRYPTO_SHA1_HMAC_96: a581 1 case CRYPTO_RIPEMD160_HMAC_96: a798 3 axf = &swcr_auth_hash_hmac_md5; goto authcommon; case CRYPTO_MD5_HMAC_96: a801 3 axf = &swcr_auth_hash_hmac_sha1; goto authcommon; case CRYPTO_SHA1_HMAC_96: a819 3 axf = &swcr_auth_hash_hmac_ripemd_160; goto authcommon; case CRYPTO_RIPEMD160_HMAC_96: a820 1 goto authcommon; /* leave this for safety */ a961 1 case CRYPTO_MD5_HMAC_96: a962 1 case CRYPTO_SHA1_HMAC_96: a964 1 case CRYPTO_RIPEMD160_HMAC_96: a1081 1 case CRYPTO_MD5_HMAC_96: a1082 1 case CRYPTO_SHA1_HMAC_96: a1084 1 case CRYPTO_RIPEMD160_HMAC_96: a1110 1 DPRINTF(("request %08x done\n", (uint32_t)crp)); a1134 1 REGISTER(CRYPTO_MD5_HMAC_96); a1135 1 REGISTER(CRYPTO_SHA1_HMAC_96); a1137 1 REGISTER(CRYPTO_RIPEMD160_HMAC_96); d1148 3 d1152 1 d1164 1 @ 1.17.22.1 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.20 2008/02/04 00:35:34 tls Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.20 2008/02/04 00:35:34 tls Exp $"); a35 1 #include "opt_ocf.h" d294 113 d521 1 d560 4 d571 1 a578 1 case CRYPTO_MD5_HMAC_96: a579 1 case CRYPTO_SHA1_HMAC_96: a581 1 case CRYPTO_RIPEMD160_HMAC_96: a798 3 axf = &swcr_auth_hash_hmac_md5; goto authcommon; case CRYPTO_MD5_HMAC_96: a801 3 axf = &swcr_auth_hash_hmac_sha1; goto authcommon; case CRYPTO_SHA1_HMAC_96: a819 3 axf = &swcr_auth_hash_hmac_ripemd_160; goto authcommon; case CRYPTO_RIPEMD160_HMAC_96: a820 1 goto authcommon; /* leave this for safety */ a961 1 case CRYPTO_MD5_HMAC_96: a962 1 case CRYPTO_SHA1_HMAC_96: a964 1 case CRYPTO_RIPEMD160_HMAC_96: a1081 1 case CRYPTO_MD5_HMAC_96: a1082 1 case CRYPTO_SHA1_HMAC_96: a1084 1 case CRYPTO_RIPEMD160_HMAC_96: a1110 1 DPRINTF(("request %08x done\n", (uint32_t)crp)); a1134 1 REGISTER(CRYPTO_MD5_HMAC_96); a1135 1 REGISTER(CRYPTO_SHA1_HMAC_96); a1137 1 REGISTER(CRYPTO_RIPEMD160_HMAC_96); d1148 3 d1152 1 d1164 1 @ 1.16 log @Add an opencrypto provider for the AES xcrypt instructions found on VIA C5P and later cores (also known as 'ACE', which is part of the VIA PadLock security engine). Ported from OpenBSD. Reviewed on tech-crypto and port-i386, no objections to commiting this. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.15 2006/11/16 01:33:51 christos Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.15 2006/11/16 01:33:51 christos Exp $"); d62 2 a63 2 static int swcr_encdec(struct cryptodesc *, struct swcr_data *, caddr_t, int); static int swcr_compdec(struct cryptodesc *, struct swcr_data *, caddr_t, int); d72 1 a72 1 swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf, d75 1 d482 1 a482 1 idat = ((caddr_t)uio->uio_iov[ind].iov_base) + k; d534 1 a534 1 struct swcr_data *sw, caddr_t buf, int outtype) d550 1 a550 1 axf->Update(&ctx, buf + crd->crd_skip, crd->crd_len); d554 2 a555 2 (int (*)(void*, caddr_t, unsigned int)) axf->Update, (caddr_t) &ctx); d566 2 a567 2 (int (*)(caddr_t, caddr_t, unsigned int)) axf->Update, (caddr_t) &ctx); d610 2 a611 1 bcopy(aalg, buf + crd->crd_inject, axf->auth_hash->authsize); d631 1 a631 1 caddr_t buf, int outtype) @ 1.16.2.1 log @file cryptosoft.c was added on branch yamt-idlelwp on 2007-03-12 06:00:50 +0000 @ text @d1 1162 @ 1.16.2.2 log @Sync with HEAD. @ text @a0 1164 /* $NetBSD: cryptosoft.c,v 1.16.2.1 2007/03/12 06:00:50 rmind Exp $ */ /* $FreeBSD: src/sys/opencrypto/cryptosoft.c,v 1.2.2.1 2002/11/21 23:34:23 sam Exp $ */ /* $OpenBSD: cryptosoft.c,v 1.35 2002/04/26 08:43:50 deraadt Exp $ */ /* * The author of this code is Angelos D. Keromytis (angelos@@cis.upenn.edu) * * This code was written by Angelos D. Keromytis in Athens, Greece, in * February 2000. Network Security Technologies Inc. (NSTI) kindly * supported the development of this code. * * Copyright (c) 2000, 2001 Angelos D. Keromytis * * Permission to use, copy, and modify this software with or without fee * is hereby granted, provided that this entire notice is included in * all source code copies of any software which is or includes a copy or * modification of this software. * * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR * PURPOSE. */ #include __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.16.2.1 2007/03/12 06:00:50 rmind Exp $"); #include #include #include #include #include #include #include #include #include #include union authctx { MD5_CTX md5ctx; SHA1_CTX sha1ctx; RMD160_CTX rmd160ctx; SHA256_CTX sha256ctx; SHA384_CTX sha384ctx; SHA512_CTX sha512ctx; }; struct swcr_data **swcr_sessions = NULL; u_int32_t swcr_sesnum = 0; int32_t swcr_id = -1; #define COPYBACK(x, a, b, c, d) \ (x) == CRYPTO_BUF_MBUF ? m_copyback((struct mbuf *)a,b,c,d) \ : cuio_copyback((struct uio *)a,b,c,d) #define COPYDATA(x, a, b, c, d) \ (x) == CRYPTO_BUF_MBUF ? m_copydata((struct mbuf *)a,b,c,d) \ : cuio_copydata((struct uio *)a,b,c,d) static int swcr_encdec(struct cryptodesc *, struct swcr_data *, void *, int); static int swcr_compdec(struct cryptodesc *, struct swcr_data *, void *, int); static int swcr_process(void *, struct cryptop *, int); static int swcr_newsession(void *, u_int32_t *, struct cryptoini *); static int swcr_freesession(void *, u_int64_t); /* * Apply a symmetric encryption/decryption algorithm. */ static int swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, void *bufv, int outtype) { char *buf = bufv; unsigned char iv[EALG_MAX_BLOCK_LEN], blk[EALG_MAX_BLOCK_LEN], *idat; unsigned char *ivp, piv[EALG_MAX_BLOCK_LEN]; const struct swcr_enc_xform *exf; int i, k, j, blks; int count, ind; exf = sw->sw_exf; blks = exf->enc_xform->blocksize; /* Check for non-padded data */ if (crd->crd_len % blks) return EINVAL; /* Initialize the IV */ if (crd->crd_flags & CRD_F_ENCRYPT) { /* IV explicitly provided ? */ if (crd->crd_flags & CRD_F_IV_EXPLICIT) bcopy(crd->crd_iv, iv, blks); else { /* Get random IV */ for (i = 0; i + sizeof (u_int32_t) < EALG_MAX_BLOCK_LEN; i += sizeof (u_int32_t)) { u_int32_t temp = arc4random(); bcopy(&temp, iv + i, sizeof(u_int32_t)); } /* * What if the block size is not a multiple * of sizeof (u_int32_t), which is the size of * what arc4random() returns ? */ if (EALG_MAX_BLOCK_LEN % sizeof (u_int32_t) != 0) { u_int32_t temp = arc4random(); bcopy (&temp, iv + i, EALG_MAX_BLOCK_LEN - i); } } /* Do we need to write the IV */ if (!(crd->crd_flags & CRD_F_IV_PRESENT)) { COPYBACK(outtype, buf, crd->crd_inject, blks, iv); } } else { /* Decryption */ /* IV explicitly provided ? */ if (crd->crd_flags & CRD_F_IV_EXPLICIT) bcopy(crd->crd_iv, iv, blks); else { /* Get IV off buf */ COPYDATA(outtype, buf, crd->crd_inject, blks, iv); } } ivp = iv; if (outtype == CRYPTO_BUF_CONTIG) { if (crd->crd_flags & CRD_F_ENCRYPT) { for (i = crd->crd_skip; i < crd->crd_skip + crd->crd_len; i += blks) { /* XOR with the IV/previous block, as appropriate. */ if (i == crd->crd_skip) for (k = 0; k < blks; k++) buf[i + k] ^= ivp[k]; else for (k = 0; k < blks; k++) buf[i + k] ^= buf[i + k - blks]; exf->encrypt(sw->sw_kschedule, buf + i); } } else { /* Decrypt */ /* * Start at the end, so we don't need to keep the encrypted * block as the IV for the next block. */ for (i = crd->crd_skip + crd->crd_len - blks; i >= crd->crd_skip; i -= blks) { exf->decrypt(sw->sw_kschedule, buf + i); /* XOR with the IV/previous block, as appropriate */ if (i == crd->crd_skip) for (k = 0; k < blks; k++) buf[i + k] ^= ivp[k]; else for (k = 0; k < blks; k++) buf[i + k] ^= buf[i + k - blks]; } } return 0; } else if (outtype == CRYPTO_BUF_MBUF) { struct mbuf *m = (struct mbuf *) buf; /* Find beginning of data */ m = m_getptr(m, crd->crd_skip, &k); if (m == NULL) return EINVAL; i = crd->crd_len; while (i > 0) { /* * If there's insufficient data at the end of * an mbuf, we have to do some copying. */ if (m->m_len < k + blks && m->m_len != k) { m_copydata(m, k, blks, blk); /* Actual encryption/decryption */ if (crd->crd_flags & CRD_F_ENCRYPT) { /* XOR with previous block */ for (j = 0; j < blks; j++) blk[j] ^= ivp[j]; exf->encrypt(sw->sw_kschedule, blk); /* * Keep encrypted block for XOR'ing * with next block */ bcopy(blk, iv, blks); ivp = iv; } else { /* decrypt */ /* * Keep encrypted block for XOR'ing * with next block */ if (ivp == iv) bcopy(blk, piv, blks); else bcopy(blk, iv, blks); exf->decrypt(sw->sw_kschedule, blk); /* XOR with previous block */ for (j = 0; j < blks; j++) blk[j] ^= ivp[j]; if (ivp == iv) bcopy(piv, iv, blks); else ivp = iv; } /* Copy back decrypted block */ m_copyback(m, k, blks, blk); /* Advance pointer */ m = m_getptr(m, k + blks, &k); if (m == NULL) return EINVAL; i -= blks; /* Could be done... */ if (i == 0) break; } /* Skip possibly empty mbufs */ if (k == m->m_len) { for (m = m->m_next; m && m->m_len == 0; m = m->m_next) ; k = 0; } /* Sanity check */ if (m == NULL) return EINVAL; /* * Warning: idat may point to garbage here, but * we only use it in the while() loop, only if * there are indeed enough data. */ idat = mtod(m, unsigned char *) + k; while (m->m_len >= k + blks && i > 0) { if (crd->crd_flags & CRD_F_ENCRYPT) { /* XOR with previous block/IV */ for (j = 0; j < blks; j++) idat[j] ^= ivp[j]; exf->encrypt(sw->sw_kschedule, idat); ivp = idat; } else { /* decrypt */ /* * Keep encrypted block to be used * in next block's processing. */ if (ivp == iv) bcopy(idat, piv, blks); else bcopy(idat, iv, blks); exf->decrypt(sw->sw_kschedule, idat); /* XOR with previous block/IV */ for (j = 0; j < blks; j++) idat[j] ^= ivp[j]; if (ivp == iv) bcopy(piv, iv, blks); else ivp = iv; } idat += blks; k += blks; i -= blks; } } return 0; /* Done with mbuf encryption/decryption */ } else if (outtype == CRYPTO_BUF_IOV) { struct uio *uio = (struct uio *) buf; #ifdef __FreeBSD__ struct iovec *iov; /* Find beginning of data */ iov = cuio_getptr(uio, crd->crd_skip, &k); if (iov == NULL) return EINVAL; i = crd->crd_len; while (i > 0) { /* * If there's insufficient data at the end of * an iovec, we have to do some copying. */ if (iov->iov_len < k + blks && iov->iov_len != k) { cuio_copydata(uio, k, blks, blk); /* Actual encryption/decryption */ if (crd->crd_flags & CRD_F_ENCRYPT) { /* XOR with previous block */ for (j = 0; j < blks; j++) blk[j] ^= ivp[j]; exf->encrypt(sw->sw_kschedule, blk); /* * Keep encrypted block for XOR'ing * with next block */ bcopy(blk, iv, blks); ivp = iv; } else { /* decrypt */ /* * Keep encrypted block for XOR'ing * with next block */ if (ivp == iv) bcopy(blk, piv, blks); else bcopy(blk, iv, blks); exf->decrypt(sw->sw_kschedule, blk); /* XOR with previous block */ for (j = 0; j < blks; j++) blk[j] ^= ivp[j]; if (ivp == iv) bcopy(piv, iv, blks); else ivp = iv; } /* Copy back decrypted block */ cuio_copyback(uio, k, blks, blk); /* Advance pointer */ iov = cuio_getptr(uio, k + blks, &k); if (iov == NULL) return EINVAL; i -= blks; /* Could be done... */ if (i == 0) break; } /* * Warning: idat may point to garbage here, but * we only use it in the while() loop, only if * there are indeed enough data. */ idat = (char *)iov->iov_base + k; while (iov->iov_len >= k + blks && i > 0) { if (crd->crd_flags & CRD_F_ENCRYPT) { /* XOR with previous block/IV */ for (j = 0; j < blks; j++) idat[j] ^= ivp[j]; exf->encrypt(sw->sw_kschedule, idat); ivp = idat; } else { /* decrypt */ /* * Keep encrypted block to be used * in next block's processing. */ if (ivp == iv) bcopy(idat, piv, blks); else bcopy(idat, iv, blks); exf->decrypt(sw->sw_kschedule, idat); /* XOR with previous block/IV */ for (j = 0; j < blks; j++) idat[j] ^= ivp[j]; if (ivp == iv) bcopy(piv, iv, blks); else ivp = iv; } idat += blks; k += blks; i -= blks; } } return 0; /* Done with mbuf encryption/decryption */ #else /* !freebsd iov */ /* Find beginning of data */ count = crd->crd_skip; ind = cuio_getptr(uio, count, &k); if (ind == -1) return EINVAL; i = crd->crd_len; while (i > 0) { /* * If there's insufficient data at the end, * we have to do some copying. */ if (uio->uio_iov[ind].iov_len < k + blks && uio->uio_iov[ind].iov_len != k) { cuio_copydata(uio, k, blks, blk); /* Actual encryption/decryption */ if (crd->crd_flags & CRD_F_ENCRYPT) { /* XOR with previous block */ for (j = 0; j < blks; j++) blk[j] ^= ivp[j]; exf->encrypt(sw->sw_kschedule, blk); /* * Keep encrypted block for XOR'ing * with next block */ bcopy(blk, iv, blks); ivp = iv; } else { /* decrypt */ /* * Keep encrypted block for XOR'ing * with next block */ if (ivp == iv) bcopy(blk, piv, blks); else bcopy(blk, iv, blks); exf->decrypt(sw->sw_kschedule, blk); /* XOR with previous block */ for (j = 0; j < blks; j++) blk[j] ^= ivp[j]; if (ivp == iv) bcopy(piv, iv, blks); else ivp = iv; } /* Copy back decrypted block */ cuio_copyback(uio, k, blks, blk); count += blks; /* Advance pointer */ ind = cuio_getptr(uio, count, &k); if (ind == -1) return (EINVAL); i -= blks; /* Could be done... */ if (i == 0) break; } /* * Warning: idat may point to garbage here, but * we only use it in the while() loop, only if * there are indeed enough data. */ idat = ((char *)uio->uio_iov[ind].iov_base) + k; while (uio->uio_iov[ind].iov_len >= k + blks && i > 0) { if (crd->crd_flags & CRD_F_ENCRYPT) { /* XOR with previous block/IV */ for (j = 0; j < blks; j++) idat[j] ^= ivp[j]; exf->encrypt(sw->sw_kschedule, idat); ivp = idat; } else { /* decrypt */ /* * Keep encrypted block to be used * in next block's processing. */ if (ivp == iv) bcopy(idat, piv, blks); else bcopy(idat, iv, blks); exf->decrypt(sw->sw_kschedule, idat); /* XOR with previous block/IV */ for (j = 0; j < blks; j++) idat[j] ^= ivp[j]; if (ivp == iv) bcopy(piv, iv, blks); else ivp = iv; } idat += blks; count += blks; k += blks; i -= blks; } } #endif return 0; /* Done with mbuf encryption/decryption */ } /* Unreachable */ return EINVAL; } /* * Compute keyed-hash authenticator. */ int swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd, struct swcr_data *sw, void *buf, int outtype) { unsigned char aalg[AALG_MAX_RESULT_LEN]; const struct swcr_auth_hash *axf; union authctx ctx; int err; if (sw->sw_ictx == 0) return EINVAL; axf = sw->sw_axf; bcopy(sw->sw_ictx, &ctx, axf->auth_hash->ctxsize); switch (outtype) { case CRYPTO_BUF_CONTIG: axf->Update(&ctx, (char *)buf + crd->crd_skip, crd->crd_len); break; case CRYPTO_BUF_MBUF: err = m_apply((struct mbuf *) buf, crd->crd_skip, crd->crd_len, (int (*)(void*, void *, unsigned int)) axf->Update, (void *) &ctx); if (err) return err; break; case CRYPTO_BUF_IOV: #ifdef __FreeBSD__ /*XXX FIXME: handle iov case*/ return EINVAL; #else err = cuio_apply((struct uio *) buf, crd->crd_skip, crd->crd_len, (int (*)(void *, void *, unsigned int)) axf->Update, (void *) &ctx); if (err) { return err; } #endif break; default: return EINVAL; } switch (sw->sw_alg) { case CRYPTO_MD5_HMAC: case CRYPTO_SHA1_HMAC: case CRYPTO_SHA2_HMAC: case CRYPTO_RIPEMD160_HMAC: if (sw->sw_octx == NULL) return EINVAL; axf->Final(aalg, &ctx); bcopy(sw->sw_octx, &ctx, axf->auth_hash->ctxsize); axf->Update(&ctx, aalg, axf->auth_hash->hashsize); axf->Final(aalg, &ctx); break; case CRYPTO_MD5_KPDK: case CRYPTO_SHA1_KPDK: if (sw->sw_octx == NULL) return EINVAL; axf->Update(&ctx, sw->sw_octx, sw->sw_klen); axf->Final(aalg, &ctx); break; case CRYPTO_NULL_HMAC: case CRYPTO_MD5: case CRYPTO_SHA1: axf->Final(aalg, &ctx); break; } /* Inject the authentication data */ switch (outtype) { case CRYPTO_BUF_CONTIG: (void)memcpy((char *)buf + crd->crd_inject, aalg, axf->auth_hash->authsize); break; case CRYPTO_BUF_MBUF: m_copyback((struct mbuf *) buf, crd->crd_inject, axf->auth_hash->authsize, aalg); break; case CRYPTO_BUF_IOV: bcopy(aalg, crp->crp_mac, axf->auth_hash->authsize); break; default: return EINVAL; } return 0; } /* * Apply a compression/decompression algorithm */ static int swcr_compdec(struct cryptodesc *crd, struct swcr_data *sw, void *buf, int outtype) { u_int8_t *data, *out; const struct swcr_comp_algo *cxf; int adj; u_int32_t result; cxf = sw->sw_cxf; /* We must handle the whole buffer of data in one time * then if there is not all the data in the mbuf, we must * copy in a buffer. */ data = malloc(crd->crd_len, M_CRYPTO_DATA, M_NOWAIT); if (data == NULL) return (EINVAL); COPYDATA(outtype, buf, crd->crd_skip, crd->crd_len, data); if (crd->crd_flags & CRD_F_COMP) result = cxf->compress(data, crd->crd_len, &out); else result = cxf->decompress(data, crd->crd_len, &out); FREE(data, M_CRYPTO_DATA); if (result == 0) return EINVAL; /* Copy back the (de)compressed data. m_copyback is * extending the mbuf as necessary. */ sw->sw_size = result; /* Check the compressed size when doing compression */ if (crd->crd_flags & CRD_F_COMP) { if (result > crd->crd_len) { /* Compression was useless, we lost time */ FREE(out, M_CRYPTO_DATA); return 0; } } COPYBACK(outtype, buf, crd->crd_skip, result, out); if (result < crd->crd_len) { adj = result - crd->crd_len; if (outtype == CRYPTO_BUF_MBUF) { adj = result - crd->crd_len; m_adj((struct mbuf *)buf, adj); } else { struct uio *uio = (struct uio *)buf; int ind; adj = crd->crd_len - result; ind = uio->uio_iovcnt - 1; while (adj > 0 && ind >= 0) { if (adj < uio->uio_iov[ind].iov_len) { uio->uio_iov[ind].iov_len -= adj; break; } adj -= uio->uio_iov[ind].iov_len; uio->uio_iov[ind].iov_len = 0; ind--; uio->uio_iovcnt--; } } } FREE(out, M_CRYPTO_DATA); return 0; } /* * Generate a new software session. */ static int swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri) { struct swcr_data **swd; const struct swcr_auth_hash *axf; const struct swcr_enc_xform *txf; const struct swcr_comp_algo *cxf; u_int32_t i; int k, error; if (sid == NULL || cri == NULL) return EINVAL; if (swcr_sessions) { for (i = 1; i < swcr_sesnum; i++) if (swcr_sessions[i] == NULL) break; } else i = 1; /* NB: to silence compiler warning */ if (swcr_sessions == NULL || i == swcr_sesnum) { if (swcr_sessions == NULL) { i = 1; /* We leave swcr_sessions[0] empty */ swcr_sesnum = CRYPTO_SW_SESSIONS; } else swcr_sesnum *= 2; swd = malloc(swcr_sesnum * sizeof(struct swcr_data *), M_CRYPTO_DATA, M_NOWAIT); if (swd == NULL) { /* Reset session number */ if (swcr_sesnum == CRYPTO_SW_SESSIONS) swcr_sesnum = 0; else swcr_sesnum /= 2; return ENOBUFS; } bzero(swd, swcr_sesnum * sizeof(struct swcr_data *)); /* Copy existing sessions */ if (swcr_sessions) { bcopy(swcr_sessions, swd, (swcr_sesnum / 2) * sizeof(struct swcr_data *)); free(swcr_sessions, M_CRYPTO_DATA); } swcr_sessions = swd; } swd = &swcr_sessions[i]; *sid = i; while (cri) { *swd = malloc(sizeof **swd, M_CRYPTO_DATA, M_NOWAIT); if (*swd == NULL) { swcr_freesession(NULL, i); return ENOBUFS; } bzero(*swd, sizeof(struct swcr_data)); switch (cri->cri_alg) { case CRYPTO_DES_CBC: txf = &swcr_enc_xform_des; goto enccommon; case CRYPTO_3DES_CBC: txf = &swcr_enc_xform_3des; goto enccommon; case CRYPTO_BLF_CBC: txf = &swcr_enc_xform_blf; goto enccommon; case CRYPTO_CAST_CBC: txf = &swcr_enc_xform_cast5; goto enccommon; case CRYPTO_SKIPJACK_CBC: txf = &swcr_enc_xform_skipjack; goto enccommon; case CRYPTO_RIJNDAEL128_CBC: txf = &swcr_enc_xform_rijndael128; goto enccommon; case CRYPTO_NULL_CBC: txf = &swcr_enc_xform_null; goto enccommon; enccommon: error = txf->setkey(&((*swd)->sw_kschedule), cri->cri_key, cri->cri_klen / 8); if (error) { swcr_freesession(NULL, i); return error; } (*swd)->sw_exf = txf; break; case CRYPTO_MD5_HMAC: axf = &swcr_auth_hash_hmac_md5_96; goto authcommon; case CRYPTO_SHA1_HMAC: axf = &swcr_auth_hash_hmac_sha1_96; goto authcommon; case CRYPTO_SHA2_HMAC: if (cri->cri_klen == 256) axf = &swcr_auth_hash_hmac_sha2_256; else if (cri->cri_klen == 384) axf = &swcr_auth_hash_hmac_sha2_384; else if (cri->cri_klen == 512) axf = &swcr_auth_hash_hmac_sha2_512; else { swcr_freesession(NULL, i); return EINVAL; } goto authcommon; case CRYPTO_NULL_HMAC: axf = &swcr_auth_hash_null; goto authcommon; case CRYPTO_RIPEMD160_HMAC: axf = &swcr_auth_hash_hmac_ripemd_160_96; authcommon: (*swd)->sw_ictx = malloc(axf->auth_hash->ctxsize, M_CRYPTO_DATA, M_NOWAIT); if ((*swd)->sw_ictx == NULL) { swcr_freesession(NULL, i); return ENOBUFS; } (*swd)->sw_octx = malloc(axf->auth_hash->ctxsize, M_CRYPTO_DATA, M_NOWAIT); if ((*swd)->sw_octx == NULL) { swcr_freesession(NULL, i); return ENOBUFS; } for (k = 0; k < cri->cri_klen / 8; k++) cri->cri_key[k] ^= HMAC_IPAD_VAL; axf->Init((*swd)->sw_ictx); axf->Update((*swd)->sw_ictx, cri->cri_key, cri->cri_klen / 8); axf->Update((*swd)->sw_ictx, hmac_ipad_buffer, HMAC_BLOCK_LEN - (cri->cri_klen / 8)); for (k = 0; k < cri->cri_klen / 8; k++) cri->cri_key[k] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL); axf->Init((*swd)->sw_octx); axf->Update((*swd)->sw_octx, cri->cri_key, cri->cri_klen / 8); axf->Update((*swd)->sw_octx, hmac_opad_buffer, HMAC_BLOCK_LEN - (cri->cri_klen / 8)); for (k = 0; k < cri->cri_klen / 8; k++) cri->cri_key[k] ^= HMAC_OPAD_VAL; (*swd)->sw_axf = axf; break; case CRYPTO_MD5_KPDK: axf = &swcr_auth_hash_key_md5; goto auth2common; case CRYPTO_SHA1_KPDK: axf = &swcr_auth_hash_key_sha1; auth2common: (*swd)->sw_ictx = malloc(axf->auth_hash->ctxsize, M_CRYPTO_DATA, M_NOWAIT); if ((*swd)->sw_ictx == NULL) { swcr_freesession(NULL, i); return ENOBUFS; } /* Store the key so we can "append" it to the payload */ (*swd)->sw_octx = malloc(cri->cri_klen / 8, M_CRYPTO_DATA, M_NOWAIT); if ((*swd)->sw_octx == NULL) { swcr_freesession(NULL, i); return ENOBUFS; } (*swd)->sw_klen = cri->cri_klen / 8; bcopy(cri->cri_key, (*swd)->sw_octx, cri->cri_klen / 8); axf->Init((*swd)->sw_ictx); axf->Update((*swd)->sw_ictx, cri->cri_key, cri->cri_klen / 8); axf->Final(NULL, (*swd)->sw_ictx); (*swd)->sw_axf = axf; break; case CRYPTO_MD5: axf = &swcr_auth_hash_md5; goto auth3common; case CRYPTO_SHA1: axf = &swcr_auth_hash_sha1; auth3common: (*swd)->sw_ictx = malloc(axf->auth_hash->ctxsize, M_CRYPTO_DATA, M_NOWAIT); if ((*swd)->sw_ictx == NULL) { swcr_freesession(NULL, i); return ENOBUFS; } axf->Init((*swd)->sw_ictx); (*swd)->sw_axf = axf; break; case CRYPTO_DEFLATE_COMP: cxf = &swcr_comp_algo_deflate; (*swd)->sw_cxf = cxf; break; default: swcr_freesession(NULL, i); return EINVAL; } (*swd)->sw_alg = cri->cri_alg; cri = cri->cri_next; swd = &((*swd)->sw_next); } return 0; } /* * Free a session. */ static int swcr_freesession(void *arg, u_int64_t tid) { struct swcr_data *swd; const struct swcr_enc_xform *txf; const struct swcr_auth_hash *axf; const struct swcr_comp_algo *cxf; u_int32_t sid = ((u_int32_t) tid) & 0xffffffff; if (sid > swcr_sesnum || swcr_sessions == NULL || swcr_sessions[sid] == NULL) return EINVAL; /* Silently accept and return */ if (sid == 0) return 0; while ((swd = swcr_sessions[sid]) != NULL) { swcr_sessions[sid] = swd->sw_next; switch (swd->sw_alg) { case CRYPTO_DES_CBC: case CRYPTO_3DES_CBC: case CRYPTO_BLF_CBC: case CRYPTO_CAST_CBC: case CRYPTO_SKIPJACK_CBC: case CRYPTO_RIJNDAEL128_CBC: case CRYPTO_NULL_CBC: txf = swd->sw_exf; if (swd->sw_kschedule) txf->zerokey(&(swd->sw_kschedule)); break; case CRYPTO_MD5_HMAC: case CRYPTO_SHA1_HMAC: case CRYPTO_SHA2_HMAC: case CRYPTO_RIPEMD160_HMAC: case CRYPTO_NULL_HMAC: axf = swd->sw_axf; if (swd->sw_ictx) { bzero(swd->sw_ictx, axf->auth_hash->ctxsize); free(swd->sw_ictx, M_CRYPTO_DATA); } if (swd->sw_octx) { bzero(swd->sw_octx, axf->auth_hash->ctxsize); free(swd->sw_octx, M_CRYPTO_DATA); } break; case CRYPTO_MD5_KPDK: case CRYPTO_SHA1_KPDK: axf = swd->sw_axf; if (swd->sw_ictx) { bzero(swd->sw_ictx, axf->auth_hash->ctxsize); free(swd->sw_ictx, M_CRYPTO_DATA); } if (swd->sw_octx) { bzero(swd->sw_octx, swd->sw_klen); free(swd->sw_octx, M_CRYPTO_DATA); } break; case CRYPTO_MD5: case CRYPTO_SHA1: axf = swd->sw_axf; if (swd->sw_ictx) free(swd->sw_ictx, M_CRYPTO_DATA); break; case CRYPTO_DEFLATE_COMP: cxf = swd->sw_cxf; break; } FREE(swd, M_CRYPTO_DATA); } return 0; } /* * Process a software request. */ static int swcr_process(void *arg, struct cryptop *crp, int hint) { struct cryptodesc *crd; struct swcr_data *sw; u_int32_t lid; int type; /* Sanity check */ if (crp == NULL) return EINVAL; if (crp->crp_desc == NULL || crp->crp_buf == NULL) { crp->crp_etype = EINVAL; goto done; } lid = crp->crp_sid & 0xffffffff; if (lid >= swcr_sesnum || lid == 0 || swcr_sessions[lid] == NULL) { crp->crp_etype = ENOENT; goto done; } if (crp->crp_flags & CRYPTO_F_IMBUF) { type = CRYPTO_BUF_MBUF; } else if (crp->crp_flags & CRYPTO_F_IOV) { type = CRYPTO_BUF_IOV; } else { type = CRYPTO_BUF_CONTIG; } /* Go through crypto descriptors, processing as we go */ for (crd = crp->crp_desc; crd; crd = crd->crd_next) { /* * Find the crypto context. * * XXX Note that the logic here prevents us from having * XXX the same algorithm multiple times in a session * XXX (or rather, we can but it won't give us the right * XXX results). To do that, we'd need some way of differentiating * XXX between the various instances of an algorithm (so we can * XXX locate the correct crypto context). */ for (sw = swcr_sessions[lid]; sw && sw->sw_alg != crd->crd_alg; sw = sw->sw_next) ; /* No such context ? */ if (sw == NULL) { crp->crp_etype = EINVAL; goto done; } switch (sw->sw_alg) { case CRYPTO_DES_CBC: case CRYPTO_3DES_CBC: case CRYPTO_BLF_CBC: case CRYPTO_CAST_CBC: case CRYPTO_SKIPJACK_CBC: case CRYPTO_RIJNDAEL128_CBC: if ((crp->crp_etype = swcr_encdec(crd, sw, crp->crp_buf, type)) != 0) goto done; break; case CRYPTO_NULL_CBC: crp->crp_etype = 0; break; case CRYPTO_MD5_HMAC: case CRYPTO_SHA1_HMAC: case CRYPTO_SHA2_HMAC: case CRYPTO_RIPEMD160_HMAC: case CRYPTO_NULL_HMAC: case CRYPTO_MD5_KPDK: case CRYPTO_SHA1_KPDK: case CRYPTO_MD5: case CRYPTO_SHA1: if ((crp->crp_etype = swcr_authcompute(crp, crd, sw, crp->crp_buf, type)) != 0) goto done; break; case CRYPTO_DEFLATE_COMP: if ((crp->crp_etype = swcr_compdec(crd, sw, crp->crp_buf, type)) != 0) goto done; else crp->crp_olen = (int)sw->sw_size; break; default: /* Unknown/unsupported algorithm */ crp->crp_etype = EINVAL; goto done; } } done: crypto_done(crp); return 0; } static void swcr_init(void) { swcr_id = crypto_get_driverid(CRYPTOCAP_F_SOFTWARE); if (swcr_id < 0) { /* This should never happen */ panic("Software crypto device cannot initialize!"); } crypto_register(swcr_id, CRYPTO_DES_CBC, 0, 0, swcr_newsession, swcr_freesession, swcr_process, NULL); #define REGISTER(alg) \ crypto_register(swcr_id, alg, 0, 0, NULL, NULL, NULL, NULL) REGISTER(CRYPTO_3DES_CBC); REGISTER(CRYPTO_BLF_CBC); REGISTER(CRYPTO_CAST_CBC); REGISTER(CRYPTO_SKIPJACK_CBC); REGISTER(CRYPTO_NULL_CBC); REGISTER(CRYPTO_MD5_HMAC); REGISTER(CRYPTO_SHA1_HMAC); REGISTER(CRYPTO_SHA2_HMAC); REGISTER(CRYPTO_RIPEMD160_HMAC); REGISTER(CRYPTO_NULL_HMAC); REGISTER(CRYPTO_MD5_KPDK); REGISTER(CRYPTO_SHA1_KPDK); REGISTER(CRYPTO_MD5); REGISTER(CRYPTO_SHA1); REGISTER(CRYPTO_RIJNDAEL128_CBC); REGISTER(CRYPTO_DEFLATE_COMP); #undef REGISTER } #ifdef __FreeBSD__ SYSINIT(cryptosoft_init, SI_SUB_PSEUDO, SI_ORDER_ANY, swcr_init, NULL) #endif #ifdef __NetBSD__ /* * Pseudo-device init routine for software crypto. */ void swcryptoattach(int); void swcryptoattach(int num) { swcr_init(); } #endif /* __NetBSD__ */ @ 1.15 log @__unused removal on arguments; approved by core. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.14 2006/10/12 01:32:47 christos Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.14 2006/10/12 01:32:47 christos Exp $"); a62 2 static int swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf, int outtype); d531 1 a531 1 static int @ 1.14 log @- sprinkle __unused on function decls. - fix a couple of unused bugs - no more -Wno-unused for i386 @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.13 2006/04/02 18:29:12 dsl Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.13 2006/04/02 18:29:12 dsl Exp $"); d706 1 a706 1 swcr_newsession(void *arg __unused, u_int32_t *sid, struct cryptoini *cri) d928 1 a928 1 swcr_freesession(void *arg __unused, u_int64_t tid) d1014 1 a1014 1 swcr_process(void *arg __unused, struct cryptop *crp, int hint __unused) d1159 1 a1159 1 swcryptoattach(int num __unused) @ 1.13 log @malloc data the size the pointer points to, not the size of a pointer. Maybe we get away with this (at least on 32bit archs) because the structure is 24 bytes and I bet the minimum allocation size is 32. Fixed coverty CIDs 2732 and 2733 @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.12 2006/03/17 23:29:11 christos Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.12 2006/03/17 23:29:11 christos Exp $"); d706 1 a706 1 swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri) d928 1 a928 1 swcr_freesession(void *arg, u_int64_t tid) d1014 1 a1014 1 swcr_process(void *arg, struct cryptop *crp, int hint) d1159 1 a1159 1 swcryptoattach(int num) @ 1.13.8.1 log @Sync with head. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.15 2006/11/16 01:33:51 christos Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.15 2006/11/16 01:33:51 christos Exp $"); @ 1.13.10.1 log @sync with head @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.13 2006/04/02 18:29:12 dsl Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.13 2006/04/02 18:29:12 dsl Exp $"); d706 1 a706 1 swcr_newsession(void *arg __unused, u_int32_t *sid, struct cryptoini *cri) d928 1 a928 1 swcr_freesession(void *arg __unused, u_int64_t tid) d1014 1 a1014 1 swcr_process(void *arg __unused, struct cryptop *crp, int hint __unused) d1159 1 a1159 1 swcryptoattach(int num __unused) @ 1.13.10.2 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.13.10.1 2006/10/22 06:07:47 yamt Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.13.10.1 2006/10/22 06:07:47 yamt Exp $"); d706 1 a706 1 swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri) d928 1 a928 1 swcr_freesession(void *arg, u_int64_t tid) d1014 1 a1014 1 swcr_process(void *arg, struct cryptop *crp, int hint) d1159 1 a1159 1 swcryptoattach(int num) @ 1.12 log @don't use MALLOC with a non-constant size; use malloc instead. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.11 2005/11/25 16:41:31 thorpej Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.11 2005/11/25 16:41:31 thorpej Exp $"); d759 1 a759 1 *swd = malloc(sizeof(*swd), M_CRYPTO_DATA, M_NOWAIT); @ 1.11 log @swcr -> swcrypto @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.10 2005/11/25 16:16:46 thorpej Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.10 2005/11/25 16:16:46 thorpej Exp $"); d645 1 a645 1 MALLOC(data, u_int8_t *, crd->crd_len, M_CRYPTO_DATA, M_NOWAIT); d759 1 a759 2 MALLOC(*swd, struct swcr_data *, sizeof(struct swcr_data), M_CRYPTO_DATA, M_NOWAIT); @ 1.11.4.1 log @sync with head @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.13 2006/04/02 18:29:12 dsl Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.13 2006/04/02 18:29:12 dsl Exp $"); d645 1 a645 1 data = malloc(crd->crd_len, M_CRYPTO_DATA, M_NOWAIT); d759 2 a760 1 *swd = malloc(sizeof **swd, M_CRYPTO_DATA, M_NOWAIT); @ 1.11.6.1 log @Sync with head. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.13 2006/04/02 18:29:12 dsl Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.13 2006/04/02 18:29:12 dsl Exp $"); d645 1 a645 1 data = malloc(crd->crd_len, M_CRYPTO_DATA, M_NOWAIT); d759 2 a760 1 *swd = malloc(sizeof **swd, M_CRYPTO_DATA, M_NOWAIT); @ 1.11.10.1 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.13 2006/04/02 18:29:12 dsl Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.13 2006/04/02 18:29:12 dsl Exp $"); d645 1 a645 1 data = malloc(crd->crd_len, M_CRYPTO_DATA, M_NOWAIT); d759 2 a760 1 *swd = malloc(sizeof **swd, M_CRYPTO_DATA, M_NOWAIT); @ 1.11.8.1 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.11 2005/11/25 16:41:31 thorpej Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.11 2005/11/25 16:41:31 thorpej Exp $"); d645 1 a645 1 data = malloc(crd->crd_len, M_CRYPTO_DATA, M_NOWAIT); d759 2 a760 1 *swd = malloc(sizeof(*swd), M_CRYPTO_DATA, M_NOWAIT); @ 1.11.8.2 log @sync with head @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.11.8.1 2006/04/01 12:07:51 yamt Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.11.8.1 2006/04/01 12:07:51 yamt Exp $"); d759 1 a759 1 *swd = malloc(sizeof **swd, M_CRYPTO_DATA, M_NOWAIT); @ 1.11.12.1 log @Merge 2006-03-28 NetBSD-current into the "peter-altq" branch. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.12 2006/03/17 23:29:11 christos Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.12 2006/03/17 23:29:11 christos Exp $"); d645 1 a645 1 data = malloc(crd->crd_len, M_CRYPTO_DATA, M_NOWAIT); d759 2 a760 1 *swd = malloc(sizeof(*swd), M_CRYPTO_DATA, M_NOWAIT); @ 1.11.12.2 log @Merge 2006-05-24 NetBSD-current into the "peter-altq" branch. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.13 2006/04/02 18:29:12 dsl Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.13 2006/04/02 18:29:12 dsl Exp $"); d759 1 a759 1 *swd = malloc(sizeof **swd, M_CRYPTO_DATA, M_NOWAIT); @ 1.10 log @- De-couple the software crypto implementation from the rest of the framework. There is no need to waste the space if you are only using algoritms provided by hardware accelerators. To get the software implementations, add "pseudo-device swcr" to your kernel config. - Lazily initialize the opencrypto framework when crypto drivers (either hardware or swcr) register themselves with the framework. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.9 2005/02/26 22:39:52 perry Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.9 2005/02/26 22:39:52 perry Exp $"); d1157 1 a1157 1 void swcrattach(int); d1160 1 a1160 1 swcrattach(int num) @ 1.9 log @nuke trailing whitespace @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.8 2003/08/27 00:20:56 thorpej Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.8 2003/08/27 00:20:56 thorpej Exp $"); d40 1 a40 10 const u_int8_t hmac_ipad_buffer[64] = { 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 }; d42 7 a48 9 const u_int8_t hmac_opad_buffer[64] = { 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C a50 1 d79 1 a79 1 struct enc_xform *exf; d84 1 a84 1 blks = exf->blocksize; d538 1 a538 1 struct auth_hash *axf; d547 1 a547 1 bcopy(sw->sw_ictx, &ctx, axf->ctxsize); d587 2 a588 2 bcopy(sw->sw_octx, &ctx, axf->ctxsize); axf->Update(&ctx, aalg, axf->hashsize); d611 1 a611 1 bcopy(aalg, buf + crd->crd_inject, axf->authsize); d615 1 a615 1 axf->authsize, aalg); d618 1 a618 1 bcopy(aalg, crp->crp_mac, axf->authsize); d634 1 a634 1 struct comp_algo *cxf; d709 3 a711 3 struct auth_hash *axf; struct enc_xform *txf; struct comp_algo *cxf; d769 1 a769 1 txf = &enc_xform_des; d772 1 a772 1 txf = &enc_xform_3des; d775 1 a775 1 txf = &enc_xform_blf; d778 1 a778 1 txf = &enc_xform_cast5; d781 1 a781 1 txf = &enc_xform_skipjack; d784 1 a784 1 txf = &enc_xform_rijndael128; d787 1 a787 1 txf = &enc_xform_null; d800 1 a800 1 axf = &auth_hash_hmac_md5_96; d803 1 a803 1 axf = &auth_hash_hmac_sha1_96; d807 1 a807 1 axf = &auth_hash_hmac_sha2_256; d809 1 a809 1 axf = &auth_hash_hmac_sha2_384; d811 1 a811 1 axf = &auth_hash_hmac_sha2_512; d818 1 a818 1 axf = &auth_hash_null; d821 1 a821 1 axf = &auth_hash_hmac_ripemd_160_96; d823 2 a824 2 (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT); d830 2 a831 2 (*swd)->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT); d861 1 a861 1 axf = &auth_hash_key_md5; d865 1 a865 1 axf = &auth_hash_key_sha1; d867 2 a868 2 (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT); d892 1 a892 1 axf = &auth_hash_md5; d896 1 a896 1 axf = &auth_hash_sha1; d898 2 a899 2 (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT); d910 1 a910 1 cxf = &comp_algo_deflate; d932 3 a934 3 struct enc_xform *txf; struct auth_hash *axf; struct comp_algo *cxf; d970 1 a970 1 bzero(swd->sw_ictx, axf->ctxsize); d974 1 a974 1 bzero(swd->sw_octx, axf->ctxsize); d984 1 a984 1 bzero(swd->sw_ictx, axf->ctxsize); d1116 1 a1116 5 /* * Initialize the driver, called from the kernel main(). */ /*static*/ void d1152 14 @ 1.9.4.1 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.9 2005/02/26 22:39:52 perry Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.9 2005/02/26 22:39:52 perry Exp $"); d40 10 a49 1 #include d51 9 a59 7 union authctx { MD5_CTX md5ctx; SHA1_CTX sha1ctx; RMD160_CTX rmd160ctx; SHA256_CTX sha256ctx; SHA384_CTX sha384ctx; SHA512_CTX sha512ctx; d62 1 d91 1 a91 1 const struct swcr_enc_xform *exf; d96 1 a96 1 blks = exf->enc_xform->blocksize; d550 1 a550 1 const struct swcr_auth_hash *axf; d559 1 a559 1 bcopy(sw->sw_ictx, &ctx, axf->auth_hash->ctxsize); d599 2 a600 2 bcopy(sw->sw_octx, &ctx, axf->auth_hash->ctxsize); axf->Update(&ctx, aalg, axf->auth_hash->hashsize); d623 1 a623 1 bcopy(aalg, buf + crd->crd_inject, axf->auth_hash->authsize); d627 1 a627 1 axf->auth_hash->authsize, aalg); d630 1 a630 1 bcopy(aalg, crp->crp_mac, axf->auth_hash->authsize); d646 1 a646 1 const struct swcr_comp_algo *cxf; d657 1 a657 1 data = malloc(crd->crd_len, M_CRYPTO_DATA, M_NOWAIT); d721 3 a723 3 const struct swcr_auth_hash *axf; const struct swcr_enc_xform *txf; const struct swcr_comp_algo *cxf; d771 2 a772 1 *swd = malloc(sizeof **swd, M_CRYPTO_DATA, M_NOWAIT); d781 1 a781 1 txf = &swcr_enc_xform_des; d784 1 a784 1 txf = &swcr_enc_xform_3des; d787 1 a787 1 txf = &swcr_enc_xform_blf; d790 1 a790 1 txf = &swcr_enc_xform_cast5; d793 1 a793 1 txf = &swcr_enc_xform_skipjack; d796 1 a796 1 txf = &swcr_enc_xform_rijndael128; d799 1 a799 1 txf = &swcr_enc_xform_null; d812 1 a812 1 axf = &swcr_auth_hash_hmac_md5_96; d815 1 a815 1 axf = &swcr_auth_hash_hmac_sha1_96; d819 1 a819 1 axf = &swcr_auth_hash_hmac_sha2_256; d821 1 a821 1 axf = &swcr_auth_hash_hmac_sha2_384; d823 1 a823 1 axf = &swcr_auth_hash_hmac_sha2_512; d830 1 a830 1 axf = &swcr_auth_hash_null; d833 1 a833 1 axf = &swcr_auth_hash_hmac_ripemd_160_96; d835 2 a836 2 (*swd)->sw_ictx = malloc(axf->auth_hash->ctxsize, M_CRYPTO_DATA, M_NOWAIT); d842 2 a843 2 (*swd)->sw_octx = malloc(axf->auth_hash->ctxsize, M_CRYPTO_DATA, M_NOWAIT); d873 1 a873 1 axf = &swcr_auth_hash_key_md5; d877 1 a877 1 axf = &swcr_auth_hash_key_sha1; d879 2 a880 2 (*swd)->sw_ictx = malloc(axf->auth_hash->ctxsize, M_CRYPTO_DATA, M_NOWAIT); d904 1 a904 1 axf = &swcr_auth_hash_md5; d908 1 a908 1 axf = &swcr_auth_hash_sha1; d910 2 a911 2 (*swd)->sw_ictx = malloc(axf->auth_hash->ctxsize, M_CRYPTO_DATA, M_NOWAIT); d922 1 a922 1 cxf = &swcr_comp_algo_deflate; d944 3 a946 3 const struct swcr_enc_xform *txf; const struct swcr_auth_hash *axf; const struct swcr_comp_algo *cxf; d982 1 a982 1 bzero(swd->sw_ictx, axf->auth_hash->ctxsize); d986 1 a986 1 bzero(swd->sw_octx, axf->auth_hash->ctxsize); d996 1 a996 1 bzero(swd->sw_ictx, axf->auth_hash->ctxsize); d1128 5 a1132 1 static void a1167 14 #ifdef __NetBSD__ /* * Pseudo-device init routine for software crypto. */ void swcryptoattach(int); void swcryptoattach(int num) { swcr_init(); } #endif /* __NetBSD__ */ @ 1.9.4.2 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.9.4.1 2006/06/21 15:12:02 yamt Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.9.4.1 2006/06/21 15:12:02 yamt Exp $"); d63 2 d533 1 a533 1 int @ 1.9.4.3 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.9.4.2 2007/02/26 09:12:08 yamt Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.9.4.2 2007/02/26 09:12:08 yamt Exp $"); d62 2 a63 2 static int swcr_encdec(struct cryptodesc *, struct swcr_data *, void *, int); static int swcr_compdec(struct cryptodesc *, struct swcr_data *, void *, int); d72 1 a72 1 swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, void *bufv, a74 1 char *buf = bufv; d481 1 a481 1 idat = ((char *)uio->uio_iov[ind].iov_base) + k; d533 1 a533 1 struct swcr_data *sw, void *buf, int outtype) d549 1 a549 1 axf->Update(&ctx, (char *)buf + crd->crd_skip, crd->crd_len); d553 2 a554 2 (int (*)(void*, void *, unsigned int)) axf->Update, (void *) &ctx); d565 2 a566 2 (int (*)(void *, void *, unsigned int)) axf->Update, (void *) &ctx); d609 1 a609 2 (void)memcpy((char *)buf + crd->crd_inject, aalg, axf->auth_hash->authsize); d629 1 a629 1 void *buf, int outtype) @ 1.9.4.4 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.9.4.3 2007/09/03 14:44:23 yamt Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.9.4.3 2007/09/03 14:44:23 yamt Exp $"); a35 1 #include "opt_ocf.h" d294 113 d521 1 d560 4 d571 1 a578 1 case CRYPTO_MD5_HMAC_96: a579 1 case CRYPTO_SHA1_HMAC_96: a581 1 case CRYPTO_RIPEMD160_HMAC_96: a798 3 axf = &swcr_auth_hash_hmac_md5; goto authcommon; case CRYPTO_MD5_HMAC_96: a801 3 axf = &swcr_auth_hash_hmac_sha1; goto authcommon; case CRYPTO_SHA1_HMAC_96: a819 3 axf = &swcr_auth_hash_hmac_ripemd_160; goto authcommon; case CRYPTO_RIPEMD160_HMAC_96: a820 1 goto authcommon; /* leave this for safety */ a961 1 case CRYPTO_MD5_HMAC_96: a962 1 case CRYPTO_SHA1_HMAC_96: a964 1 case CRYPTO_RIPEMD160_HMAC_96: a1081 1 case CRYPTO_MD5_HMAC_96: a1082 1 case CRYPTO_SHA1_HMAC_96: a1084 1 case CRYPTO_RIPEMD160_HMAC_96: a1110 1 DPRINTF(("request %08x done\n", (uint32_t)crp)); a1134 1 REGISTER(CRYPTO_MD5_HMAC_96); a1135 1 REGISTER(CRYPTO_SHA1_HMAC_96); a1137 1 REGISTER(CRYPTO_RIPEMD160_HMAC_96); d1148 3 d1152 1 d1164 1 @ 1.9.10.1 log @sync with head. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.9 2005/02/26 22:39:52 perry Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.9 2005/02/26 22:39:52 perry Exp $"); d40 10 a49 1 #include d51 9 a59 7 union authctx { MD5_CTX md5ctx; SHA1_CTX sha1ctx; RMD160_CTX rmd160ctx; SHA256_CTX sha256ctx; SHA384_CTX sha384ctx; SHA512_CTX sha512ctx; d62 1 d91 1 a91 1 const struct swcr_enc_xform *exf; d96 1 a96 1 blks = exf->enc_xform->blocksize; d550 1 a550 1 const struct swcr_auth_hash *axf; d559 1 a559 1 bcopy(sw->sw_ictx, &ctx, axf->auth_hash->ctxsize); d599 2 a600 2 bcopy(sw->sw_octx, &ctx, axf->auth_hash->ctxsize); axf->Update(&ctx, aalg, axf->auth_hash->hashsize); d623 1 a623 1 bcopy(aalg, buf + crd->crd_inject, axf->auth_hash->authsize); d627 1 a627 1 axf->auth_hash->authsize, aalg); d630 1 a630 1 bcopy(aalg, crp->crp_mac, axf->auth_hash->authsize); d646 1 a646 1 const struct swcr_comp_algo *cxf; d721 3 a723 3 const struct swcr_auth_hash *axf; const struct swcr_enc_xform *txf; const struct swcr_comp_algo *cxf; d781 1 a781 1 txf = &swcr_enc_xform_des; d784 1 a784 1 txf = &swcr_enc_xform_3des; d787 1 a787 1 txf = &swcr_enc_xform_blf; d790 1 a790 1 txf = &swcr_enc_xform_cast5; d793 1 a793 1 txf = &swcr_enc_xform_skipjack; d796 1 a796 1 txf = &swcr_enc_xform_rijndael128; d799 1 a799 1 txf = &swcr_enc_xform_null; d812 1 a812 1 axf = &swcr_auth_hash_hmac_md5_96; d815 1 a815 1 axf = &swcr_auth_hash_hmac_sha1_96; d819 1 a819 1 axf = &swcr_auth_hash_hmac_sha2_256; d821 1 a821 1 axf = &swcr_auth_hash_hmac_sha2_384; d823 1 a823 1 axf = &swcr_auth_hash_hmac_sha2_512; d830 1 a830 1 axf = &swcr_auth_hash_null; d833 1 a833 1 axf = &swcr_auth_hash_hmac_ripemd_160_96; d835 2 a836 2 (*swd)->sw_ictx = malloc(axf->auth_hash->ctxsize, M_CRYPTO_DATA, M_NOWAIT); d842 2 a843 2 (*swd)->sw_octx = malloc(axf->auth_hash->ctxsize, M_CRYPTO_DATA, M_NOWAIT); d873 1 a873 1 axf = &swcr_auth_hash_key_md5; d877 1 a877 1 axf = &swcr_auth_hash_key_sha1; d879 2 a880 2 (*swd)->sw_ictx = malloc(axf->auth_hash->ctxsize, M_CRYPTO_DATA, M_NOWAIT); d904 1 a904 1 axf = &swcr_auth_hash_md5; d908 1 a908 1 axf = &swcr_auth_hash_sha1; d910 2 a911 2 (*swd)->sw_ictx = malloc(axf->auth_hash->ctxsize, M_CRYPTO_DATA, M_NOWAIT); d922 1 a922 1 cxf = &swcr_comp_algo_deflate; d944 3 a946 3 const struct swcr_enc_xform *txf; const struct swcr_auth_hash *axf; const struct swcr_comp_algo *cxf; d982 1 a982 1 bzero(swd->sw_ictx, axf->auth_hash->ctxsize); d986 1 a986 1 bzero(swd->sw_octx, axf->auth_hash->ctxsize); d996 1 a996 1 bzero(swd->sw_ictx, axf->auth_hash->ctxsize); d1128 5 a1132 1 static void a1167 14 #ifdef __NetBSD__ /* * Pseudo-device init routine for software crypto. */ void swcryptoattach(int); void swcryptoattach(int num) { swcr_init(); } #endif /* __NetBSD__ */ @ 1.8 log @Some const poisoning. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.7 2003/08/26 15:03:26 thorpej Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.7 2003/08/26 15:03:26 thorpej Exp $"); d339 1 a339 1 /* d534 1 a534 1 #endif d1109 1 a1109 1 if ((crp->crp_etype = swcr_compdec(crd, sw, @ 1.8.4.1 log @file cryptosoft.c was added on branch ktrace-lwp on 2004-08-03 10:56:25 +0000 @ text @d1 1167 @ 1.8.4.2 log @Sync with HEAD @ text @a0 1167 /* $NetBSD: cryptosoft.c,v 1.8.4.1 2004/08/03 10:56:25 skrll Exp $ */ /* $FreeBSD: src/sys/opencrypto/cryptosoft.c,v 1.2.2.1 2002/11/21 23:34:23 sam Exp $ */ /* $OpenBSD: cryptosoft.c,v 1.35 2002/04/26 08:43:50 deraadt Exp $ */ /* * The author of this code is Angelos D. Keromytis (angelos@@cis.upenn.edu) * * This code was written by Angelos D. Keromytis in Athens, Greece, in * February 2000. Network Security Technologies Inc. (NSTI) kindly * supported the development of this code. * * Copyright (c) 2000, 2001 Angelos D. Keromytis * * Permission to use, copy, and modify this software with or without fee * is hereby granted, provided that this entire notice is included in * all source code copies of any software which is or includes a copy or * modification of this software. * * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR * PURPOSE. */ #include __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.8.4.1 2004/08/03 10:56:25 skrll Exp $"); #include #include #include #include #include #include #include #include #include const u_int8_t hmac_ipad_buffer[64] = { 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 }; const u_int8_t hmac_opad_buffer[64] = { 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C }; struct swcr_data **swcr_sessions = NULL; u_int32_t swcr_sesnum = 0; int32_t swcr_id = -1; #define COPYBACK(x, a, b, c, d) \ (x) == CRYPTO_BUF_MBUF ? m_copyback((struct mbuf *)a,b,c,d) \ : cuio_copyback((struct uio *)a,b,c,d) #define COPYDATA(x, a, b, c, d) \ (x) == CRYPTO_BUF_MBUF ? m_copydata((struct mbuf *)a,b,c,d) \ : cuio_copydata((struct uio *)a,b,c,d) static int swcr_encdec(struct cryptodesc *, struct swcr_data *, caddr_t, int); static int swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf, int outtype); static int swcr_compdec(struct cryptodesc *, struct swcr_data *, caddr_t, int); static int swcr_process(void *, struct cryptop *, int); static int swcr_newsession(void *, u_int32_t *, struct cryptoini *); static int swcr_freesession(void *, u_int64_t); /* * Apply a symmetric encryption/decryption algorithm. */ static int swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf, int outtype) { unsigned char iv[EALG_MAX_BLOCK_LEN], blk[EALG_MAX_BLOCK_LEN], *idat; unsigned char *ivp, piv[EALG_MAX_BLOCK_LEN]; struct enc_xform *exf; int i, k, j, blks; int count, ind; exf = sw->sw_exf; blks = exf->blocksize; /* Check for non-padded data */ if (crd->crd_len % blks) return EINVAL; /* Initialize the IV */ if (crd->crd_flags & CRD_F_ENCRYPT) { /* IV explicitly provided ? */ if (crd->crd_flags & CRD_F_IV_EXPLICIT) bcopy(crd->crd_iv, iv, blks); else { /* Get random IV */ for (i = 0; i + sizeof (u_int32_t) < EALG_MAX_BLOCK_LEN; i += sizeof (u_int32_t)) { u_int32_t temp = arc4random(); bcopy(&temp, iv + i, sizeof(u_int32_t)); } /* * What if the block size is not a multiple * of sizeof (u_int32_t), which is the size of * what arc4random() returns ? */ if (EALG_MAX_BLOCK_LEN % sizeof (u_int32_t) != 0) { u_int32_t temp = arc4random(); bcopy (&temp, iv + i, EALG_MAX_BLOCK_LEN - i); } } /* Do we need to write the IV */ if (!(crd->crd_flags & CRD_F_IV_PRESENT)) { COPYBACK(outtype, buf, crd->crd_inject, blks, iv); } } else { /* Decryption */ /* IV explicitly provided ? */ if (crd->crd_flags & CRD_F_IV_EXPLICIT) bcopy(crd->crd_iv, iv, blks); else { /* Get IV off buf */ COPYDATA(outtype, buf, crd->crd_inject, blks, iv); } } ivp = iv; if (outtype == CRYPTO_BUF_CONTIG) { if (crd->crd_flags & CRD_F_ENCRYPT) { for (i = crd->crd_skip; i < crd->crd_skip + crd->crd_len; i += blks) { /* XOR with the IV/previous block, as appropriate. */ if (i == crd->crd_skip) for (k = 0; k < blks; k++) buf[i + k] ^= ivp[k]; else for (k = 0; k < blks; k++) buf[i + k] ^= buf[i + k - blks]; exf->encrypt(sw->sw_kschedule, buf + i); } } else { /* Decrypt */ /* * Start at the end, so we don't need to keep the encrypted * block as the IV for the next block. */ for (i = crd->crd_skip + crd->crd_len - blks; i >= crd->crd_skip; i -= blks) { exf->decrypt(sw->sw_kschedule, buf + i); /* XOR with the IV/previous block, as appropriate */ if (i == crd->crd_skip) for (k = 0; k < blks; k++) buf[i + k] ^= ivp[k]; else for (k = 0; k < blks; k++) buf[i + k] ^= buf[i + k - blks]; } } return 0; } else if (outtype == CRYPTO_BUF_MBUF) { struct mbuf *m = (struct mbuf *) buf; /* Find beginning of data */ m = m_getptr(m, crd->crd_skip, &k); if (m == NULL) return EINVAL; i = crd->crd_len; while (i > 0) { /* * If there's insufficient data at the end of * an mbuf, we have to do some copying. */ if (m->m_len < k + blks && m->m_len != k) { m_copydata(m, k, blks, blk); /* Actual encryption/decryption */ if (crd->crd_flags & CRD_F_ENCRYPT) { /* XOR with previous block */ for (j = 0; j < blks; j++) blk[j] ^= ivp[j]; exf->encrypt(sw->sw_kschedule, blk); /* * Keep encrypted block for XOR'ing * with next block */ bcopy(blk, iv, blks); ivp = iv; } else { /* decrypt */ /* * Keep encrypted block for XOR'ing * with next block */ if (ivp == iv) bcopy(blk, piv, blks); else bcopy(blk, iv, blks); exf->decrypt(sw->sw_kschedule, blk); /* XOR with previous block */ for (j = 0; j < blks; j++) blk[j] ^= ivp[j]; if (ivp == iv) bcopy(piv, iv, blks); else ivp = iv; } /* Copy back decrypted block */ m_copyback(m, k, blks, blk); /* Advance pointer */ m = m_getptr(m, k + blks, &k); if (m == NULL) return EINVAL; i -= blks; /* Could be done... */ if (i == 0) break; } /* Skip possibly empty mbufs */ if (k == m->m_len) { for (m = m->m_next; m && m->m_len == 0; m = m->m_next) ; k = 0; } /* Sanity check */ if (m == NULL) return EINVAL; /* * Warning: idat may point to garbage here, but * we only use it in the while() loop, only if * there are indeed enough data. */ idat = mtod(m, unsigned char *) + k; while (m->m_len >= k + blks && i > 0) { if (crd->crd_flags & CRD_F_ENCRYPT) { /* XOR with previous block/IV */ for (j = 0; j < blks; j++) idat[j] ^= ivp[j]; exf->encrypt(sw->sw_kschedule, idat); ivp = idat; } else { /* decrypt */ /* * Keep encrypted block to be used * in next block's processing. */ if (ivp == iv) bcopy(idat, piv, blks); else bcopy(idat, iv, blks); exf->decrypt(sw->sw_kschedule, idat); /* XOR with previous block/IV */ for (j = 0; j < blks; j++) idat[j] ^= ivp[j]; if (ivp == iv) bcopy(piv, iv, blks); else ivp = iv; } idat += blks; k += blks; i -= blks; } } return 0; /* Done with mbuf encryption/decryption */ } else if (outtype == CRYPTO_BUF_IOV) { struct uio *uio = (struct uio *) buf; #ifdef __FreeBSD__ struct iovec *iov; /* Find beginning of data */ iov = cuio_getptr(uio, crd->crd_skip, &k); if (iov == NULL) return EINVAL; i = crd->crd_len; while (i > 0) { /* * If there's insufficient data at the end of * an iovec, we have to do some copying. */ if (iov->iov_len < k + blks && iov->iov_len != k) { cuio_copydata(uio, k, blks, blk); /* Actual encryption/decryption */ if (crd->crd_flags & CRD_F_ENCRYPT) { /* XOR with previous block */ for (j = 0; j < blks; j++) blk[j] ^= ivp[j]; exf->encrypt(sw->sw_kschedule, blk); /* * Keep encrypted block for XOR'ing * with next block */ bcopy(blk, iv, blks); ivp = iv; } else { /* decrypt */ /* * Keep encrypted block for XOR'ing * with next block */ if (ivp == iv) bcopy(blk, piv, blks); else bcopy(blk, iv, blks); exf->decrypt(sw->sw_kschedule, blk); /* XOR with previous block */ for (j = 0; j < blks; j++) blk[j] ^= ivp[j]; if (ivp == iv) bcopy(piv, iv, blks); else ivp = iv; } /* Copy back decrypted block */ cuio_copyback(uio, k, blks, blk); /* Advance pointer */ iov = cuio_getptr(uio, k + blks, &k); if (iov == NULL) return EINVAL; i -= blks; /* Could be done... */ if (i == 0) break; } /* * Warning: idat may point to garbage here, but * we only use it in the while() loop, only if * there are indeed enough data. */ idat = (char *)iov->iov_base + k; while (iov->iov_len >= k + blks && i > 0) { if (crd->crd_flags & CRD_F_ENCRYPT) { /* XOR with previous block/IV */ for (j = 0; j < blks; j++) idat[j] ^= ivp[j]; exf->encrypt(sw->sw_kschedule, idat); ivp = idat; } else { /* decrypt */ /* * Keep encrypted block to be used * in next block's processing. */ if (ivp == iv) bcopy(idat, piv, blks); else bcopy(idat, iv, blks); exf->decrypt(sw->sw_kschedule, idat); /* XOR with previous block/IV */ for (j = 0; j < blks; j++) idat[j] ^= ivp[j]; if (ivp == iv) bcopy(piv, iv, blks); else ivp = iv; } idat += blks; k += blks; i -= blks; } } return 0; /* Done with mbuf encryption/decryption */ #else /* !freebsd iov */ /* Find beginning of data */ count = crd->crd_skip; ind = cuio_getptr(uio, count, &k); if (ind == -1) return EINVAL; i = crd->crd_len; while (i > 0) { /* * If there's insufficient data at the end, * we have to do some copying. */ if (uio->uio_iov[ind].iov_len < k + blks && uio->uio_iov[ind].iov_len != k) { cuio_copydata(uio, k, blks, blk); /* Actual encryption/decryption */ if (crd->crd_flags & CRD_F_ENCRYPT) { /* XOR with previous block */ for (j = 0; j < blks; j++) blk[j] ^= ivp[j]; exf->encrypt(sw->sw_kschedule, blk); /* * Keep encrypted block for XOR'ing * with next block */ bcopy(blk, iv, blks); ivp = iv; } else { /* decrypt */ /* * Keep encrypted block for XOR'ing * with next block */ if (ivp == iv) bcopy(blk, piv, blks); else bcopy(blk, iv, blks); exf->decrypt(sw->sw_kschedule, blk); /* XOR with previous block */ for (j = 0; j < blks; j++) blk[j] ^= ivp[j]; if (ivp == iv) bcopy(piv, iv, blks); else ivp = iv; } /* Copy back decrypted block */ cuio_copyback(uio, k, blks, blk); count += blks; /* Advance pointer */ ind = cuio_getptr(uio, count, &k); if (ind == -1) return (EINVAL); i -= blks; /* Could be done... */ if (i == 0) break; } /* * Warning: idat may point to garbage here, but * we only use it in the while() loop, only if * there are indeed enough data. */ idat = ((caddr_t)uio->uio_iov[ind].iov_base) + k; while (uio->uio_iov[ind].iov_len >= k + blks && i > 0) { if (crd->crd_flags & CRD_F_ENCRYPT) { /* XOR with previous block/IV */ for (j = 0; j < blks; j++) idat[j] ^= ivp[j]; exf->encrypt(sw->sw_kschedule, idat); ivp = idat; } else { /* decrypt */ /* * Keep encrypted block to be used * in next block's processing. */ if (ivp == iv) bcopy(idat, piv, blks); else bcopy(idat, iv, blks); exf->decrypt(sw->sw_kschedule, idat); /* XOR with previous block/IV */ for (j = 0; j < blks; j++) idat[j] ^= ivp[j]; if (ivp == iv) bcopy(piv, iv, blks); else ivp = iv; } idat += blks; count += blks; k += blks; i -= blks; } } #endif return 0; /* Done with mbuf encryption/decryption */ } /* Unreachable */ return EINVAL; } /* * Compute keyed-hash authenticator. */ static int swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf, int outtype) { unsigned char aalg[AALG_MAX_RESULT_LEN]; struct auth_hash *axf; union authctx ctx; int err; if (sw->sw_ictx == 0) return EINVAL; axf = sw->sw_axf; bcopy(sw->sw_ictx, &ctx, axf->ctxsize); switch (outtype) { case CRYPTO_BUF_CONTIG: axf->Update(&ctx, buf + crd->crd_skip, crd->crd_len); break; case CRYPTO_BUF_MBUF: err = m_apply((struct mbuf *) buf, crd->crd_skip, crd->crd_len, (int (*)(void*, caddr_t, unsigned int)) axf->Update, (caddr_t) &ctx); if (err) return err; break; case CRYPTO_BUF_IOV: #ifdef __FreeBSD__ /*XXX FIXME: handle iov case*/ return EINVAL; #else err = cuio_apply((struct uio *) buf, crd->crd_skip, crd->crd_len, (int (*)(caddr_t, caddr_t, unsigned int)) axf->Update, (caddr_t) &ctx); if (err) { return err; } #endif break; default: return EINVAL; } switch (sw->sw_alg) { case CRYPTO_MD5_HMAC: case CRYPTO_SHA1_HMAC: case CRYPTO_SHA2_HMAC: case CRYPTO_RIPEMD160_HMAC: if (sw->sw_octx == NULL) return EINVAL; axf->Final(aalg, &ctx); bcopy(sw->sw_octx, &ctx, axf->ctxsize); axf->Update(&ctx, aalg, axf->hashsize); axf->Final(aalg, &ctx); break; case CRYPTO_MD5_KPDK: case CRYPTO_SHA1_KPDK: if (sw->sw_octx == NULL) return EINVAL; axf->Update(&ctx, sw->sw_octx, sw->sw_klen); axf->Final(aalg, &ctx); break; case CRYPTO_NULL_HMAC: case CRYPTO_MD5: case CRYPTO_SHA1: axf->Final(aalg, &ctx); break; } /* Inject the authentication data */ switch (outtype) { case CRYPTO_BUF_CONTIG: bcopy(aalg, buf + crd->crd_inject, axf->authsize); break; case CRYPTO_BUF_MBUF: m_copyback((struct mbuf *) buf, crd->crd_inject, axf->authsize, aalg); break; case CRYPTO_BUF_IOV: bcopy(aalg, crp->crp_mac, axf->authsize); break; default: return EINVAL; } return 0; } /* * Apply a compression/decompression algorithm */ static int swcr_compdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf, int outtype) { u_int8_t *data, *out; struct comp_algo *cxf; int adj; u_int32_t result; cxf = sw->sw_cxf; /* We must handle the whole buffer of data in one time * then if there is not all the data in the mbuf, we must * copy in a buffer. */ MALLOC(data, u_int8_t *, crd->crd_len, M_CRYPTO_DATA, M_NOWAIT); if (data == NULL) return (EINVAL); COPYDATA(outtype, buf, crd->crd_skip, crd->crd_len, data); if (crd->crd_flags & CRD_F_COMP) result = cxf->compress(data, crd->crd_len, &out); else result = cxf->decompress(data, crd->crd_len, &out); FREE(data, M_CRYPTO_DATA); if (result == 0) return EINVAL; /* Copy back the (de)compressed data. m_copyback is * extending the mbuf as necessary. */ sw->sw_size = result; /* Check the compressed size when doing compression */ if (crd->crd_flags & CRD_F_COMP) { if (result > crd->crd_len) { /* Compression was useless, we lost time */ FREE(out, M_CRYPTO_DATA); return 0; } } COPYBACK(outtype, buf, crd->crd_skip, result, out); if (result < crd->crd_len) { adj = result - crd->crd_len; if (outtype == CRYPTO_BUF_MBUF) { adj = result - crd->crd_len; m_adj((struct mbuf *)buf, adj); } else { struct uio *uio = (struct uio *)buf; int ind; adj = crd->crd_len - result; ind = uio->uio_iovcnt - 1; while (adj > 0 && ind >= 0) { if (adj < uio->uio_iov[ind].iov_len) { uio->uio_iov[ind].iov_len -= adj; break; } adj -= uio->uio_iov[ind].iov_len; uio->uio_iov[ind].iov_len = 0; ind--; uio->uio_iovcnt--; } } } FREE(out, M_CRYPTO_DATA); return 0; } /* * Generate a new software session. */ static int swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri) { struct swcr_data **swd; struct auth_hash *axf; struct enc_xform *txf; struct comp_algo *cxf; u_int32_t i; int k, error; if (sid == NULL || cri == NULL) return EINVAL; if (swcr_sessions) { for (i = 1; i < swcr_sesnum; i++) if (swcr_sessions[i] == NULL) break; } else i = 1; /* NB: to silence compiler warning */ if (swcr_sessions == NULL || i == swcr_sesnum) { if (swcr_sessions == NULL) { i = 1; /* We leave swcr_sessions[0] empty */ swcr_sesnum = CRYPTO_SW_SESSIONS; } else swcr_sesnum *= 2; swd = malloc(swcr_sesnum * sizeof(struct swcr_data *), M_CRYPTO_DATA, M_NOWAIT); if (swd == NULL) { /* Reset session number */ if (swcr_sesnum == CRYPTO_SW_SESSIONS) swcr_sesnum = 0; else swcr_sesnum /= 2; return ENOBUFS; } bzero(swd, swcr_sesnum * sizeof(struct swcr_data *)); /* Copy existing sessions */ if (swcr_sessions) { bcopy(swcr_sessions, swd, (swcr_sesnum / 2) * sizeof(struct swcr_data *)); free(swcr_sessions, M_CRYPTO_DATA); } swcr_sessions = swd; } swd = &swcr_sessions[i]; *sid = i; while (cri) { MALLOC(*swd, struct swcr_data *, sizeof(struct swcr_data), M_CRYPTO_DATA, M_NOWAIT); if (*swd == NULL) { swcr_freesession(NULL, i); return ENOBUFS; } bzero(*swd, sizeof(struct swcr_data)); switch (cri->cri_alg) { case CRYPTO_DES_CBC: txf = &enc_xform_des; goto enccommon; case CRYPTO_3DES_CBC: txf = &enc_xform_3des; goto enccommon; case CRYPTO_BLF_CBC: txf = &enc_xform_blf; goto enccommon; case CRYPTO_CAST_CBC: txf = &enc_xform_cast5; goto enccommon; case CRYPTO_SKIPJACK_CBC: txf = &enc_xform_skipjack; goto enccommon; case CRYPTO_RIJNDAEL128_CBC: txf = &enc_xform_rijndael128; goto enccommon; case CRYPTO_NULL_CBC: txf = &enc_xform_null; goto enccommon; enccommon: error = txf->setkey(&((*swd)->sw_kschedule), cri->cri_key, cri->cri_klen / 8); if (error) { swcr_freesession(NULL, i); return error; } (*swd)->sw_exf = txf; break; case CRYPTO_MD5_HMAC: axf = &auth_hash_hmac_md5_96; goto authcommon; case CRYPTO_SHA1_HMAC: axf = &auth_hash_hmac_sha1_96; goto authcommon; case CRYPTO_SHA2_HMAC: if (cri->cri_klen == 256) axf = &auth_hash_hmac_sha2_256; else if (cri->cri_klen == 384) axf = &auth_hash_hmac_sha2_384; else if (cri->cri_klen == 512) axf = &auth_hash_hmac_sha2_512; else { swcr_freesession(NULL, i); return EINVAL; } goto authcommon; case CRYPTO_NULL_HMAC: axf = &auth_hash_null; goto authcommon; case CRYPTO_RIPEMD160_HMAC: axf = &auth_hash_hmac_ripemd_160_96; authcommon: (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT); if ((*swd)->sw_ictx == NULL) { swcr_freesession(NULL, i); return ENOBUFS; } (*swd)->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT); if ((*swd)->sw_octx == NULL) { swcr_freesession(NULL, i); return ENOBUFS; } for (k = 0; k < cri->cri_klen / 8; k++) cri->cri_key[k] ^= HMAC_IPAD_VAL; axf->Init((*swd)->sw_ictx); axf->Update((*swd)->sw_ictx, cri->cri_key, cri->cri_klen / 8); axf->Update((*swd)->sw_ictx, hmac_ipad_buffer, HMAC_BLOCK_LEN - (cri->cri_klen / 8)); for (k = 0; k < cri->cri_klen / 8; k++) cri->cri_key[k] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL); axf->Init((*swd)->sw_octx); axf->Update((*swd)->sw_octx, cri->cri_key, cri->cri_klen / 8); axf->Update((*swd)->sw_octx, hmac_opad_buffer, HMAC_BLOCK_LEN - (cri->cri_klen / 8)); for (k = 0; k < cri->cri_klen / 8; k++) cri->cri_key[k] ^= HMAC_OPAD_VAL; (*swd)->sw_axf = axf; break; case CRYPTO_MD5_KPDK: axf = &auth_hash_key_md5; goto auth2common; case CRYPTO_SHA1_KPDK: axf = &auth_hash_key_sha1; auth2common: (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT); if ((*swd)->sw_ictx == NULL) { swcr_freesession(NULL, i); return ENOBUFS; } /* Store the key so we can "append" it to the payload */ (*swd)->sw_octx = malloc(cri->cri_klen / 8, M_CRYPTO_DATA, M_NOWAIT); if ((*swd)->sw_octx == NULL) { swcr_freesession(NULL, i); return ENOBUFS; } (*swd)->sw_klen = cri->cri_klen / 8; bcopy(cri->cri_key, (*swd)->sw_octx, cri->cri_klen / 8); axf->Init((*swd)->sw_ictx); axf->Update((*swd)->sw_ictx, cri->cri_key, cri->cri_klen / 8); axf->Final(NULL, (*swd)->sw_ictx); (*swd)->sw_axf = axf; break; case CRYPTO_MD5: axf = &auth_hash_md5; goto auth3common; case CRYPTO_SHA1: axf = &auth_hash_sha1; auth3common: (*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT); if ((*swd)->sw_ictx == NULL) { swcr_freesession(NULL, i); return ENOBUFS; } axf->Init((*swd)->sw_ictx); (*swd)->sw_axf = axf; break; case CRYPTO_DEFLATE_COMP: cxf = &comp_algo_deflate; (*swd)->sw_cxf = cxf; break; default: swcr_freesession(NULL, i); return EINVAL; } (*swd)->sw_alg = cri->cri_alg; cri = cri->cri_next; swd = &((*swd)->sw_next); } return 0; } /* * Free a session. */ static int swcr_freesession(void *arg, u_int64_t tid) { struct swcr_data *swd; struct enc_xform *txf; struct auth_hash *axf; struct comp_algo *cxf; u_int32_t sid = ((u_int32_t) tid) & 0xffffffff; if (sid > swcr_sesnum || swcr_sessions == NULL || swcr_sessions[sid] == NULL) return EINVAL; /* Silently accept and return */ if (sid == 0) return 0; while ((swd = swcr_sessions[sid]) != NULL) { swcr_sessions[sid] = swd->sw_next; switch (swd->sw_alg) { case CRYPTO_DES_CBC: case CRYPTO_3DES_CBC: case CRYPTO_BLF_CBC: case CRYPTO_CAST_CBC: case CRYPTO_SKIPJACK_CBC: case CRYPTO_RIJNDAEL128_CBC: case CRYPTO_NULL_CBC: txf = swd->sw_exf; if (swd->sw_kschedule) txf->zerokey(&(swd->sw_kschedule)); break; case CRYPTO_MD5_HMAC: case CRYPTO_SHA1_HMAC: case CRYPTO_SHA2_HMAC: case CRYPTO_RIPEMD160_HMAC: case CRYPTO_NULL_HMAC: axf = swd->sw_axf; if (swd->sw_ictx) { bzero(swd->sw_ictx, axf->ctxsize); free(swd->sw_ictx, M_CRYPTO_DATA); } if (swd->sw_octx) { bzero(swd->sw_octx, axf->ctxsize); free(swd->sw_octx, M_CRYPTO_DATA); } break; case CRYPTO_MD5_KPDK: case CRYPTO_SHA1_KPDK: axf = swd->sw_axf; if (swd->sw_ictx) { bzero(swd->sw_ictx, axf->ctxsize); free(swd->sw_ictx, M_CRYPTO_DATA); } if (swd->sw_octx) { bzero(swd->sw_octx, swd->sw_klen); free(swd->sw_octx, M_CRYPTO_DATA); } break; case CRYPTO_MD5: case CRYPTO_SHA1: axf = swd->sw_axf; if (swd->sw_ictx) free(swd->sw_ictx, M_CRYPTO_DATA); break; case CRYPTO_DEFLATE_COMP: cxf = swd->sw_cxf; break; } FREE(swd, M_CRYPTO_DATA); } return 0; } /* * Process a software request. */ static int swcr_process(void *arg, struct cryptop *crp, int hint) { struct cryptodesc *crd; struct swcr_data *sw; u_int32_t lid; int type; /* Sanity check */ if (crp == NULL) return EINVAL; if (crp->crp_desc == NULL || crp->crp_buf == NULL) { crp->crp_etype = EINVAL; goto done; } lid = crp->crp_sid & 0xffffffff; if (lid >= swcr_sesnum || lid == 0 || swcr_sessions[lid] == NULL) { crp->crp_etype = ENOENT; goto done; } if (crp->crp_flags & CRYPTO_F_IMBUF) { type = CRYPTO_BUF_MBUF; } else if (crp->crp_flags & CRYPTO_F_IOV) { type = CRYPTO_BUF_IOV; } else { type = CRYPTO_BUF_CONTIG; } /* Go through crypto descriptors, processing as we go */ for (crd = crp->crp_desc; crd; crd = crd->crd_next) { /* * Find the crypto context. * * XXX Note that the logic here prevents us from having * XXX the same algorithm multiple times in a session * XXX (or rather, we can but it won't give us the right * XXX results). To do that, we'd need some way of differentiating * XXX between the various instances of an algorithm (so we can * XXX locate the correct crypto context). */ for (sw = swcr_sessions[lid]; sw && sw->sw_alg != crd->crd_alg; sw = sw->sw_next) ; /* No such context ? */ if (sw == NULL) { crp->crp_etype = EINVAL; goto done; } switch (sw->sw_alg) { case CRYPTO_DES_CBC: case CRYPTO_3DES_CBC: case CRYPTO_BLF_CBC: case CRYPTO_CAST_CBC: case CRYPTO_SKIPJACK_CBC: case CRYPTO_RIJNDAEL128_CBC: if ((crp->crp_etype = swcr_encdec(crd, sw, crp->crp_buf, type)) != 0) goto done; break; case CRYPTO_NULL_CBC: crp->crp_etype = 0; break; case CRYPTO_MD5_HMAC: case CRYPTO_SHA1_HMAC: case CRYPTO_SHA2_HMAC: case CRYPTO_RIPEMD160_HMAC: case CRYPTO_NULL_HMAC: case CRYPTO_MD5_KPDK: case CRYPTO_SHA1_KPDK: case CRYPTO_MD5: case CRYPTO_SHA1: if ((crp->crp_etype = swcr_authcompute(crp, crd, sw, crp->crp_buf, type)) != 0) goto done; break; case CRYPTO_DEFLATE_COMP: if ((crp->crp_etype = swcr_compdec(crd, sw, crp->crp_buf, type)) != 0) goto done; else crp->crp_olen = (int)sw->sw_size; break; default: /* Unknown/unsupported algorithm */ crp->crp_etype = EINVAL; goto done; } } done: crypto_done(crp); return 0; } /* * Initialize the driver, called from the kernel main(). */ /*static*/ void swcr_init(void) { swcr_id = crypto_get_driverid(CRYPTOCAP_F_SOFTWARE); if (swcr_id < 0) { /* This should never happen */ panic("Software crypto device cannot initialize!"); } crypto_register(swcr_id, CRYPTO_DES_CBC, 0, 0, swcr_newsession, swcr_freesession, swcr_process, NULL); #define REGISTER(alg) \ crypto_register(swcr_id, alg, 0, 0, NULL, NULL, NULL, NULL) REGISTER(CRYPTO_3DES_CBC); REGISTER(CRYPTO_BLF_CBC); REGISTER(CRYPTO_CAST_CBC); REGISTER(CRYPTO_SKIPJACK_CBC); REGISTER(CRYPTO_NULL_CBC); REGISTER(CRYPTO_MD5_HMAC); REGISTER(CRYPTO_SHA1_HMAC); REGISTER(CRYPTO_SHA2_HMAC); REGISTER(CRYPTO_RIPEMD160_HMAC); REGISTER(CRYPTO_NULL_HMAC); REGISTER(CRYPTO_MD5_KPDK); REGISTER(CRYPTO_SHA1_KPDK); REGISTER(CRYPTO_MD5); REGISTER(CRYPTO_SHA1); REGISTER(CRYPTO_RIJNDAEL128_CBC); REGISTER(CRYPTO_DEFLATE_COMP); #undef REGISTER } #ifdef __FreeBSD__ SYSINIT(cryptosoft_init, SI_SUB_PSEUDO, SI_ORDER_ANY, swcr_init, NULL) #endif @ 1.8.4.3 log @Sync with HEAD. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.8.4.2 2004/09/18 14:56:20 skrll Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.8.4.2 2004/09/18 14:56:20 skrll Exp $"); @ 1.8.4.4 log @Fix the sync with head I botched. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.8.4.3 2004/09/21 13:38:44 skrll Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.8.4.3 2004/09/21 13:38:44 skrll Exp $"); @ 1.8.4.5 log @Sync with HEAD. Hi Perry! @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.8.4.4 2005/03/04 16:54:22 skrll Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.8.4.4 2005/03/04 16:54:22 skrll Exp $"); d339 1 a339 1 /* d534 1 a534 1 #endif d1109 1 a1109 1 if ((crp->crp_etype = swcr_compdec(crd, sw, @ 1.8.4.6 log @Sync with head. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.8.4.5 2005/12/11 10:29:36 christos Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.8.4.5 2005/12/11 10:29:36 christos Exp $"); d40 10 a49 1 #include d51 9 a59 7 union authctx { MD5_CTX md5ctx; SHA1_CTX sha1ctx; RMD160_CTX rmd160ctx; SHA256_CTX sha256ctx; SHA384_CTX sha384ctx; SHA512_CTX sha512ctx; d62 1 d91 1 a91 1 const struct swcr_enc_xform *exf; d96 1 a96 1 blks = exf->enc_xform->blocksize; d550 1 a550 1 const struct swcr_auth_hash *axf; d559 1 a559 1 bcopy(sw->sw_ictx, &ctx, axf->auth_hash->ctxsize); d599 2 a600 2 bcopy(sw->sw_octx, &ctx, axf->auth_hash->ctxsize); axf->Update(&ctx, aalg, axf->auth_hash->hashsize); d623 1 a623 1 bcopy(aalg, buf + crd->crd_inject, axf->auth_hash->authsize); d627 1 a627 1 axf->auth_hash->authsize, aalg); d630 1 a630 1 bcopy(aalg, crp->crp_mac, axf->auth_hash->authsize); d646 1 a646 1 const struct swcr_comp_algo *cxf; d721 3 a723 3 const struct swcr_auth_hash *axf; const struct swcr_enc_xform *txf; const struct swcr_comp_algo *cxf; d781 1 a781 1 txf = &swcr_enc_xform_des; d784 1 a784 1 txf = &swcr_enc_xform_3des; d787 1 a787 1 txf = &swcr_enc_xform_blf; d790 1 a790 1 txf = &swcr_enc_xform_cast5; d793 1 a793 1 txf = &swcr_enc_xform_skipjack; d796 1 a796 1 txf = &swcr_enc_xform_rijndael128; d799 1 a799 1 txf = &swcr_enc_xform_null; d812 1 a812 1 axf = &swcr_auth_hash_hmac_md5_96; d815 1 a815 1 axf = &swcr_auth_hash_hmac_sha1_96; d819 1 a819 1 axf = &swcr_auth_hash_hmac_sha2_256; d821 1 a821 1 axf = &swcr_auth_hash_hmac_sha2_384; d823 1 a823 1 axf = &swcr_auth_hash_hmac_sha2_512; d830 1 a830 1 axf = &swcr_auth_hash_null; d833 1 a833 1 axf = &swcr_auth_hash_hmac_ripemd_160_96; d835 2 a836 2 (*swd)->sw_ictx = malloc(axf->auth_hash->ctxsize, M_CRYPTO_DATA, M_NOWAIT); d842 2 a843 2 (*swd)->sw_octx = malloc(axf->auth_hash->ctxsize, M_CRYPTO_DATA, M_NOWAIT); d873 1 a873 1 axf = &swcr_auth_hash_key_md5; d877 1 a877 1 axf = &swcr_auth_hash_key_sha1; d879 2 a880 2 (*swd)->sw_ictx = malloc(axf->auth_hash->ctxsize, M_CRYPTO_DATA, M_NOWAIT); d904 1 a904 1 axf = &swcr_auth_hash_md5; d908 1 a908 1 axf = &swcr_auth_hash_sha1; d910 2 a911 2 (*swd)->sw_ictx = malloc(axf->auth_hash->ctxsize, M_CRYPTO_DATA, M_NOWAIT); d922 1 a922 1 cxf = &swcr_comp_algo_deflate; d944 3 a946 3 const struct swcr_enc_xform *txf; const struct swcr_auth_hash *axf; const struct swcr_comp_algo *cxf; d982 1 a982 1 bzero(swd->sw_ictx, axf->auth_hash->ctxsize); d986 1 a986 1 bzero(swd->sw_octx, axf->auth_hash->ctxsize); d996 1 a996 1 bzero(swd->sw_ictx, axf->auth_hash->ctxsize); d1128 5 a1132 1 static void a1167 14 #ifdef __NetBSD__ /* * Pseudo-device init routine for software crypto. */ void swcryptoattach(int); void swcryptoattach(int num) { swcr_init(); } #endif /* __NetBSD__ */ @ 1.8.10.1 log @sync with -current @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.9 2005/02/26 22:39:52 perry Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.9 2005/02/26 22:39:52 perry Exp $"); d339 1 a339 1 /* d534 1 a534 1 #endif d1109 1 a1109 1 if ((crp->crp_etype = swcr_compdec(crd, sw, @ 1.8.12.1 log @sync with head. xen and whitespace. xen part is not finished. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.8 2003/08/27 00:20:56 thorpej Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.8 2003/08/27 00:20:56 thorpej Exp $"); d339 1 a339 1 /* d534 1 a534 1 #endif d1109 1 a1109 1 if ((crp->crp_etype = swcr_compdec(crd, sw, @ 1.7 log @Remove a bunch of unnecessary includes. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.6 2003/08/25 04:09:57 thorpej Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.6 2003/08/25 04:09:57 thorpej Exp $"); d40 1 a40 1 u_int8_t hmac_ipad_buffer[64] = { d51 1 a51 1 u_int8_t hmac_opad_buffer[64] = { @ 1.6 log @It's bad form to use the header file while using the crypto/ripemd160/rmd160.c implementation. Remove the opencrypto-local copies of these files entirely. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.5 2003/07/30 18:20:16 jonathan Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.5 2003/07/30 18:20:16 jonathan Exp $"); a34 2 #include #include a35 5 #include #include #include #include @ 1.5 log @Garbage-collect references to OpenBSD-only . @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.4 2003/07/28 19:37:04 jonathan Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.4 2003/07/28 19:37:04 jonathan Exp $"); d38 2 a39 1 #include @ 1.4 log @Remove vestiges of OpenBSD header. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.3 2003/07/27 03:34:40 jonathan Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.3 2003/07/27 03:34:40 jonathan Exp $"); d37 1 a37 1 #include @ 1.3 log @Cleanup traces of previous standalone m_apply()/m_getptr(). @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.2 2003/07/26 22:53:44 jonathan Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.2 2003/07/26 22:53:44 jonathan Exp $"); d35 1 a35 1 #include @ 1.2 log @Fix authentication hashes requested via /dev/crypto. The handler for userland hashes case was partly omitted in the OpenBSD -> FreeBSD port. @ text @d1 1 a1 1 /* $NetBSD: cryptosoft.c,v 1.1 2003/07/25 21:12:45 jonathan Exp $ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.1 2003/07/25 21:12:45 jonathan Exp $"); a88 7 * NB: These came over from openbsd and are kept private * to the crypto code for now. */ extern int m_apply(struct mbuf *m, int off, int len, int (*f)(caddr_t, caddr_t, unsigned int), caddr_t fstate); /* d573 1 a573 1 (int (*)(caddr_t, caddr_t, unsigned int)) axf->Update, @ 1.1 log @Commit initial NetBSD port of the OpenCrypto Framework (OCF). This code is derived from Sam Leffler's FreeBSD port of OCF, which is in turn a port of Angelos Keromytis's OpenBSD work. Credit to Sam and Angelos, any blame for the NetBSD port to me. @ text @d1 1 a1 1 /* $NetBSD:$ */ d27 1 a27 1 __KERNEL_RCSID(0, "$NetBSD:$"); d586 13 d634 2 a635 1 if (outtype == CRYPTO_BUF_CONTIG) d637 2 a638 1 else d641 7 @